2011-09-27 48 views
0

正確的索引我有如下表:我MySQL查詢

CREATE TABLE `sal_forwarding` (
    `sid` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `f_shop` INT(11) NOT NULL, 
    `f_offer` INT(11) DEFAULT NULL, 
    . 
    . 
    . 
    PRIMARY KEY (`sid`), 
    KEY `forwardTime` (`forwardTime`,`f_shop`), 
    KEY `forwardTime_2` (`forwardTime`), 
    KEY `f_shop` (`f_shop`) 
) ENGINE=INNODB AUTO_INCREMENT=10457068 DEFAULT CHARSET=latin1 

這個表已經超過500萬行。

我已經設置了索引,如上所見,但在我的查詢中沒有使用索引,我不明白爲什麼。有人看到我的問題嗎?

說明:

EXPLAIN SELECT 
    f_shop 
    , COUNT(sid) 
    , SUM(IF(toolbarUser=1,1,0)) 
FROM sal_forwarding 
WHERE DATE(forwardTime) = "2011-09-01" 
GROUP BY f_shop 

結果:

+----+-------------+----------------+-------+---------------+--------+---------+--------+--------+-------------+ 
| ID | SELECT_TYPE |  TABLE  | TYPE | POSSIBLE_KEYS | KEY | KEY_LEN | REF | ROWS | EXTRA | 
+----+-------------+----------------+-------+---------------+--------+---------+--------+--------+-------------+ 
| |    |    |  |    |  |   |  |  |    | 
| 1 | SIMPLE  | sal_forwarding | index | (NULL)  | f_shop | 4  | (NULL) | 232449 | Using where | 
+----+-------------+----------------+-------+---------------+--------+---------+--------+--------+-------------+ 
+0

當我將查詢更改爲:EXPLAIN SELECT f_shop,COUNT(sid),SUM(IF(toolbarUser = 1,1,0))FROM sal_forwarding GROUP BY f_shop。沒有使用索引。我刪除了DATE()函數,並且沒有使用索引。 :( – user954740

+0

@dnagirl,你有正確的答案,你爲什麼要刪除它? – Johan

+0

作爲一個新手,你可能想開始接受你的問題的答案找到解決方案。這樣,它給了那些幫助和其他人將在未來繼續提供幫助...尋找答案左側的複選標記並檢查解決方案是否有效,還可以幫助其他人搜索舊問題,以便在早已提前解決問題時提供解決方案解決方案: – DRapp

回答

2

MySQL不能在函數內部列中使用的索引。
從您的選擇中刪除函數date(),MySQL將使用索引。

您可以通過改變forwardtime你列定義這樣做是爲了DATE
或者你可以更改查詢,像這樣

SELECT 
    f_shop 
    , COUNT(*) as RowCount 
    , SUM(toolbarUser=1) as NumberOfToolbarUsers 
FROM sal_forwarding 
WHERE forwardTime BETWEEN '2011-09-01 00:00' AND '2011-09-01 23:59' 
GROUP BY f_shop 

備註

  • count(*)count(namedcolumn)快;如果爲真,則(a = 1)=> 0,因此可以縮短if(a=1,1,0);
  • 這是一個好主意,可以爲您的聚合列別名,因此您可以稍後通過其別名引用它們。
  • 如果添加下列索引(並刪除索引forwardtime),則查詢運行速度會更快。 KEY fasttime (forwardTime,f_shop,toolbarUser)
  • 以前的觀點在InnoDB上尤其如此,如果可能的話,MySQL將使用覆蓋索引,這意味着如果它能夠在索引中找到所需的所有數據,它將永遠不會讀取表來檢索數據。
+0

也許你可以補充說一個'(f_shop,forwardTime)'索引將會有所幫助 –

+0

或者是一個'(forwardTime)',取決於分佈 –

+0

@ypercube,你仍然在訪問'toolbaruser',所以我懷疑 – Johan