2012-04-24 46 views
0

我有一個約1000萬個條目的數據庫,每個條目都包含一個存儲爲DATE的日期。在mysql中快速搜索不同的日期部分

我已經使用非唯一的BTREE索引了該列。

我運行登載項的每個不同的年份數的查詢:

SELECT DISTINCT(YEAR(awesome_date)) as year, COUNT(id) as count 
FROM all_entries 
WHERE awesome_date IS NOT NULL 
GROUP BY YEAR(awesome_date) 
ORDER BY year DESC; 

查詢需要大約90秒,在目前運行,並且EXPLAIN輸出證明了爲什麼:

id | select_type | table  | type | possible_keys | key | key_len | ref | rows  | Extra 
---------------------------------------------------------------------------------------------------------------------------------------- 
1 | SIMPLE  | all_entries | ALL | awesome_date |  |   |  | 9759848 | Using where; Using temporary; Using filesort 

如果我將FORCE KEY(awesome_date)下降的行數減少到〜800萬,並且key_len = 4,但仍然是Using where; Using temporary; Using filesort

我也運行查詢選擇DISTINCT(MONTH(awesome_date))DISTINCT(DAY(awesome_date))與相關的WHERE條件限制他們到一個特定的年份或月份。

除了將年份,月份和日期信息存儲在單獨的列中,是否有加快此查詢和/或避免臨時表和文件夾的方法?

回答

1

,不要把日期3列,你可以:

  • 首先,你應該刪除DISTINCT,它是無用的。 - ypercube 1分鐘前編輯

  • 取出ORDER BY year,這將有助於提高速度(位)。將Group By更改爲:GROUP BY YEAR(awesome_date) DESC(僅適用於MySQL方言)。

  • 更改COUNT(id)COUNT(*)(假設id永遠不能NULL,這在許多版本的MySQL更快)。

在所有的查詢將變爲:

SELECT YEAR(awesome_date) AS year 
    , COUNT(*) AS cnt    --- not good practise to use reserved words 
            --- for aliases 
FROM all_entries 
WHERE awesome_date IS NOT NULL 
GROUP BY YEAR(awesome_date) DESC ; 

更妙(快)的解決方案是:

  • 你的建議列分成3(年,月,日)

  • chang從MySQL到MariaDB(即MySQL分支),並使用VIRTUAL PERISTENT列,並在該虛擬列上添加索引。

  • 留在MySQL中,自己添加一個持久的year列 - 通過使用觸發器。

+0

@Jon:有幫助嗎? – 2012-04-24 15:15:19