Задать вопрос
@drboboev

Как посчитать сумму детей необходимого узла за каждый день месяца (Nested Set)?

Добрый день.

Дано: Имеется иерархическая структура типа Nested Set, 6 уровней - таблица structure. Таблица sales, куда заносятся продажи каждый день по нижним уровням иерархии (те, у кого нет "детей"). Поля: structure_id, date, sum.

Мне необходимо сделать следующее: По запросу я должен получить сумму продаж за каждый день текущего месяца по любому узлу. Т.е. мне нужно получить сумму по узлу с id = 6. Запросом я должен вытащить из базы структуру и посчитать продажи за каждый день месяца (т.е. максимально - 31).

Я сделал необходимый запрос, но он занимает 6 секунд, что недопустимо. Мне нужен максимально быстрый запрос.

Конечно, мои знания синтаксиса SQL довольно примитивны, поэтому обращаюсь к знатокам.
  • Вопрос задан
  • 405 просмотров
Подписаться 2 Оценить 1 комментарий
Решения вопроса 1
@remzalp
Программер чего попало на чем попало
Изучите GROUP BY, который в случае с MySQL всё аккуратно отсортирует, сгруппирует, а за компанию и посчитает сумму.

Не понимаю, откуда взялся и как работает getTreeSum(), мне кажется какой-то лишний оверкилл может происходить внутри.

Дальше - допишите EXPLAIN перед своим запросом и покажите результат - это скажет, в каких местах всё плохо.

Подозреваю, запрос должен делиться на 2 части - вывод идшников дочерних узлов вложенным подзапросом и SUMмма по полученному:
WHERE id IN (select .... left_key >= левый_ключ_необходимого_узла AND right_key <= правый_ключ_необходимого_узла)
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
то есть запрос по типу select * from structure where parent_id = 6 занимает 6 секунд?
Какой запрос используете, какая структура у таблицы structure?
Ответ написан
Комментировать
@drboboev Автор вопроса
ThunderCat
таблица structure
поля: id, name, left_key, right_key, level

Когда мне нужно посчитать продажи за месяц, я использую запрос
SELECT *, (SELECT getTreeSum(left_key, right_key, startDate, endDate)) as sum FROM structure
LEFT JOIN sales ON structure.id = sales.structure_id
WHERE left_key >= левый_ключ_необходимого_узла AND right_key <= правый_ключ_необходимого_узла
и все работает, правда делается два запроса, но это не так критично. getTreeSum это моя функция, которая считает сумму всех дочерних узлов за определенный период startDate - endDate.

Но если делать по аналогии за каждый день, то получается длинный запрос (потому что по каждому дню параметры будут startDate = endDate и запрос будет выполнятся долго, потому что получается запросов 1 + количество_дней_в_месяце. Т.е. минимум 28 запросов! Вот я и хочу найти более быстрый запрос
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы