2016-11-29 5 views
0

Im используя запрос ниже, чтобы рассчитать 5 лучших расходов на каждую отдельную компанию и отсортировать их по убыванию. В настоящее время таблица имеет около 3 миллионов строк и занимает около 8 секунд для правильного выполнения. Я ищу способ ускорить это.Как я могу ускорить этот запрос SUM?

SELECT 
    SUM(cost) as sumw, 
    company FROM cost 
WHERE 
    datetime BETWEEN '2016-10-01' AND '2016-12-01' 
GROUP BY company 
ORDER BY sumw desc 
LIMIT 5; 

datetime имеет индекс.

EXPLAIN:

1 SIMPLE cost NULL ALL datetime NULL NULL NULL 3204715 50.00 Using where; Using temporary; Using filesort 

СОЗДАТЬ

CREATE TABLE `cost` (
    `id` bigint(8) unsigned NOT NULL AUTO_INCREMENT, 
    `company` varchar(45) DEFAULT NULL, 
    `cost` bigint(8) unsigned DEFAULT NULL, 
    `datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `datetime` (`datetime`) 
) ENGINE=InnoDB AUTO_INCREMENT=3335830 DEFAULT CHARSET=utf8; 
+0

добавить оборудование; или генерировать итоговые данные ежедневно/ежечасно перед запросом. SQL выглядит так же эффективно, как и может быть. Может быть, перечислить строки в датах, чтобы она не косвенно делала это, но я не могу себе представить, что это принесет вам много. Вне MySQL я могу предложить материализованное представление с периодическим обновлением, но MySQL их не имеет. – xQbert

+1

Обычно при запросе справки о производительности SQL отображаются отображаемые определения таблиц, включая индексы. Также неплохо показать вывод 'EXPLAIN'. –

+0

добавлено info @ O.Jones – Ray

ответ

1

индекс соединения на вашем cost таблице на (datetime, company, cost) может быть в состоянии улучшить производительность запроса. Это стоит попробовать, особенно если в таблице cost есть много других столбцов, не участвующих в этом запросе.

Обратите внимание на что-то в вашем запросе.

datetime BETWEEN '2016-10-01' AND '2016-12-01' 

извлекает все строки со значениями от 1-октября-2016 в полночь 1-Dec-2016 полночь включительно. Вы можете

datetime >= '2016-01-01' AND datetime < '2016-12-01' 

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

+0

Запрос используется должным образом. Телефонные даты, на которые добавлен этот вопрос. – Ray

+0

Добавление индексов уменьшило их на 2 секунды – Ray

+0

сначала добавьте составной индекс, чтобы ускорить запрос ** ALTER TABLE 'cost' добавить ключ idx_date_company (' datetime', 'company'); ** и снова проверить. отправьте новый EXPLAIN –

1

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

ALTER TABLE cost ADD INDEX(company); 

Надеюсь, это поможет.

+0

С уважением, это неверно. Запрос MySQL может (по состоянию на конец 2016 года) использовать только один индекс. И доминирующей частью запроса этого вопросника является поиск диапазона в столбце 'datetime'. –