2016-11-29 193 views
0

Im使用下面的查詢來計算每個公司排名前5的費用並對它們進行排序。目前該表有大約300萬行,需要大約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有一個索引。

說明:

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

CREATE

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

補充信息@ O.Jones – Ray

回答

1

一個複合索引您cost表上(datetime, company, cost)可能能夠改善查詢的性能。值得一試,特別是如果cost表中有許多其他列未涉及此查詢。

請注意查詢中的內容。

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

檢索所有與1 - 10月-2016午夜到1 - 12月-2016午夜包容值的行。您可能想要

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

如果您要處理10月和11月的數據。這第二個公式在使用您的指數時比第一個公式效率更低。

+0

查詢正在使用正確。電話日期爲此問題添加。 – Ray

+0

添加索引減少了2秒 – Ray

+0

首先添加一個複合索引以加快查詢** ALTER TABLE'cost'添加鍵idx_date_company('datetime','company'); **並再次測試。請發佈新的解釋 –

1

您的查詢是按公司計算的結果,因此它需要公司專欄的索引。

ALTER TABLE cost ADD INDEX(company); 

希望這會有所幫助。

+0

尊重,這是不正確的。 MySQL查詢可以(截至2016年底)僅利用單個索引。此提問者查詢的主要部分是'datetime'列中的範圍搜索。 –