2016-07-14 2 views
-1

Я пытаюсь получить общее количество с использованием подзапроса. (Я использую Metabase, который, кажется, не принимают/переменных процесса в запросах)Подзапрос без дополнительной колонки занимает больше времени, чем в столбце

Мой запрос:

SELECT date_format(t.`session_stop`, '%d') AS `session_stop`, 
    sum(t.`energy_used`/1000) AS `csum`, 
    (
     SELECT (SUM(a.`energy_used`)/1000) 
     FROM `sessions` a 
     WHERE date_format(a.`session_stop`, '%Y-%m-%d') <= date_format(t.`session_stop`, '%Y-%m-%d') 
     AND str_to_date(concat(date_format(a.`session_stop`, '%Y-%m'), '-01'), '%Y-%m-%d') = str_to_date(concat(date_format(now(), '%Y-%m'), '-01'), '%Y-%m-%d') 
     ORDER BY str_to_date(date_format(a.`session_stop`, '%e'), '%d') ASC 
    ) AS `sum` 
    FROM `sessions` t 
    WHERE str_to_date(concat(date_format(t.`session_stop`, '%Y-%m'), '-01'), '%Y-%m-%d') = str_to_date(concat(date_format(now(), '%Y-%m'), '-01'), '%Y-%m-%d') 
    GROUP BY date_format(t.`session_stop`, '%e') 
    ORDER BY str_to_date(date_format(t.`session_stop`, '%d'), '%d') ASC; 

Это занимает около 1.29secs бежать. (43K строк в целом, возврат 14)

Если я удаляю линию sum(t.`energy_used`/1000) AS `csum`,, запрос занимает 8 минут и 40 секунд.

Почему это? Я бы предпочел не иметь эту строку, но я также не могу дождаться 8 минут для обработки запроса.

(я знаю, что может создать кумулятивный столбец, но я особенно заинтересован, почему эта дополнительная sum() ускоряет весь запрос вверх)

пса. протестировал это как на консоли MySQL, так и на интерфейсе Metabase.

EXPLAIN запрос:

+----+--------------------+-------+------+---------------+------+---------+------+-------+--------------------------- 
| id | select_type  | table | type | possible_keys | key | key_len | ref | rows | Extra 
+----+--------------------+-------+------+---------------+------+---------+------+-------+--------------------------- 
| 1 | PRIMARY   | t  | ALL | NULL   | NULL | NULL | NULL | 42055 | Using where; Using tempora 
| 2 | DEPENDENT SUBQUERY | a  | ALL | NULL   | NULL | NULL | NULL | 42055 | Using where 
+----+--------------------+-------+------+---------------+------+---------+------+-------+--------------------------- 
2 rows in set (0.00 sec) 

Без дополнительной sum():

+----+--------------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+ 
| id | select_type  | table | type | possible_keys | key | key_len | ref | rows | Extra          | 
+----+--------------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+ 
| 1 | PRIMARY   | t  | ALL | NULL   | NULL | NULL | NULL | 44976 | Using where; Using temporary; Using filesort | 
| 2 | DEPENDENT SUBQUERY | a  | ALL | NULL   | NULL | NULL | NULL | 44976 | Using where         | 
+----+--------------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+ 
2 rows in set (0.00 sec) 

схема не намного больше, чем за столом с:

session_id (INT, auto incr., prim.key) | session_stop (datetime) | energy_used (INT) | 
1       | 1-1-2016 10:00:00  | 123456   | 
2       | 1-1-2016 10:05:00  | 123456   | 
3       | 1-2-2016 10:10:00  | 123456   | 
4       | 1-2-2016 12:00:00  | 123456   | 
5       | 3-3-2016 14:05:00  | 123456   | 

Некоторые примеры на интернетах шоу с использованием ID для предложения WHERE, но у меня были некоторые плохие результаты.

+1

высокоуровневый обзор запуска его через «Объяснение» может помочь. Кроме того, ваша схема. – Drew

+0

Забыл добавить: (Это сейчас.(Я предположил, что могу что-то делать по индексам, но результаты на самом деле не показывают этого) – puredevotion

+1

Что вы еще можете объяснить. Какова ваша схема. – Drew

ответ

1

Ваши запросы не похожи. Фактически, они являются полюсами.

Если удалить сумму (т. energy_used/1000) А.С. csum, линии, запрос занимает 8 минут и 40 секунд.

Когда вы используете СУММ, это агрегация. sum(t. energy_used / 1000) произведет совершенно другой результат, просто выбрав t.energy_used, поэтому существует такая огромная разница в таймингах запросов.

Это также очень понятно, почему вы сравниваете даты таким образом:

WHERE date_format(a.`session_stop`, '%Y-%m-%d') <=  date_format(t.`session_stop`, '%Y-%m-%d') 

Почему вы преобразуя их обоих с date_format перед тем Comparision? Поскольку обе таблицы, по-видимому, содержат один и тот же тип данных, вы должны иметь возможность делать a.session_stop <= t.session_stop, это будет намного быстрее для обоих случаев.

Поскольку это сравнение неравенства, это не хороший кандидат для индексов, но вы все равно можете попытаться создать индекс в этом столбце, чтобы узнать, имеет ли он никакого эффекта.

Таким образом, разница в производительности заключается в том, что вы не просто добавляете/удаляете дополнительный столбец, а добавляете/удаляете агрегацию.

Смежные вопросы