2016-10-03 83 views
0

好吧,我有以下MySQL表結構:MySQL的多列索引

CREATE TABLE `creditlog` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `memberId` int(10) unsigned NOT NULL, 
    `quantity` decimal(10,2) unsigned DEFAULT NULL, 
    `timeAdded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `reference` varchar(255) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `memberId` (`memberId`), 
    KEY `timeAdded` (`timeAdded`)); 

而我查詢這樣的:

SELECT SUM(quantity) FROM creditlog where timeAdded>'2016-09-01' AND timeAdded<'2016-10-01' AND memberId IN (3,6,8,9,11) 

現在,我也用use index (timeAdded)因爲由於條目數量更方便。解釋上面的查詢顯示:

type -> range, 
key -> timeAdded, 
rows -> 921294 
extra -> using where 

同時,如果我使用memberId INDEX它表明:

type -> range, 
key -> memberId, 
rows -> 1707849 
extra -> using where 

現在,我的問題是,它可能這兩個指標在某種程度上結合起來一起使用,降低了因爲我還需要添加更多條件(在其他列上)。

+0

是你想創建(timeAdded,memberId)的索引。 – khalid

+0

我有興趣確定訂單實際上 – Samson

+0

您測試過嗎? – khalid

回答

0

MySQL幾乎從不在一個查詢中使用兩個索引;它只是不符合成本效益。但是,複合索引通常非常有效。您需要此訂單:INDEX(memberId, timeAdded)

建立索引這樣...

  1. 首先包括與=測試WHERE子句中的列(S)。 (無,你的情況。)
  2. 任何列與IN
  3. 一個 '範圍',如<BETWEEN
  4. 移動到GROUP BYORDER BY的所有字段。 (這裏不相關)

有很多例外和注意事項。有些在我的cookbook中給出。

(流行的觀點相反,基數是在設計指標幾乎沒有相關性。)

這裏是一個比較兩個指標(即使表是太小,無法得到可靠的計時)方式:

FLUSH STATUS; 
SELECT SQL_NO_CACHE ...; 
SHOW SESSION STATUS LIKE 'Handler%'; 
(repeat for other query/index) 

較小的數字幾乎總是表示更好。

「timeAdded>'2016-09-01'AND timeadded <'2016-10-01'」 - 這不包括第一天的午夜。我推薦這種模式:

timeAdded >= '2016-09-01' 
AND timeAdded < '2016-09-01' + INTERVAL 1 MONTH 

這也避免了計算日期。

聞起來像一個普通的查詢?您是否考慮過構建和維護Summary tables?等效查詢的運行速度可能會快10倍。