簡體   English   中英

哪個復合索引會使這個簡單的MySQL查詢更快?

[英]Which Composite Index would make this simple MySQL query faster?

哪個復合索引可以使這個簡單的MySQL查詢更快 ,我將如何創建該復合索引?

SELECT * 
FROM  `Table1` 
WHERE  `col1` =  '145307'
AND  `col2` =  '0'
AND col3 NOT 
IN ( 130209, 130839 ) 
ORDER BY col4 DESC 
LIMIT 0 , 5

上面的每列上都有一個單獨的索引( col1col4 )。


編輯

SHOW CREATE TABLE結果:

CREATE TABLE `Table1` (  
 `primaryCol` int(11) NOT NULL AUTO_INCREMENT,
 `col3` int(11) DEFAULT '0',
 `col5` varchar(20) COLLATE utf8_bin DEFAULT NULL,
 `col1` int(11) DEFAULT '0',
 `col6` varchar(80) COLLATE utf8_bin DEFAULT NULL,
 `col7` text CHARACTER SET utf8,
 `col4` int(11) DEFAULT '0',
 `col8` char(1) COLLATE utf8_bin DEFAULT 'N',
 `col9` char(1) COLLATE utf8_bin DEFAULT 'N',
 `col2` tinyint(1) NOT NULL,
 `col10` tinyint(1) NOT NULL,
 `col11` smallint(6) NOT NULL,
 PRIMARY KEY (`primaryCol`),
 KEY `col5` (`col5`),
 KEY `col1` (`col1`),
 KEY `col3` (`col3`),
 KEY `col4` (`col4`),
 KEY `col8` (`col8`),
 KEY `col9` (`col9`),
 KEY `CompIndex1` (`col1`,`col8`,`col4`),
 KEY `col2` (`col2`),
 KEY `col10` (`col10`),
 KEY `col11` (`col11`),
 FULLTEXT KEY `col7` (`col7`)
) ENGINE=MyISAM AUTO_INCREMENT=4575350 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

EXPLAIN EXTENDED結果:

id  select_type table   type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  Table1  ref col1,col3,CompIndex1,col2   CompIndex1  5   const   226 100 Using where; Using filesort

我會建議一個索引(col1,col2,col3)。

mysql> CREATE INDEX NewIndex ON Table1 (col1,col2,col3);

mysql> EXPLAIN SELECT *  FROM  `Table1`  WHERE  `col1` =  '145307' 
AND  `col2` =  '0' AND col3 NOT  IN ( 130209, 130839 )  
ORDER BY col4 DESC  LIMIT 0 , 5\G

           id: 1
  select_type: SIMPLE
        table: Table1
         type: ref
possible_keys: col1,col3,CompIndex1,col2,NewIndex
          key: NewIndex
      key_len: 6
          ref: const,const
         rows: 1
        Extra: Using where; Using filesort

你在col3上的條件不是相等比較,它是一個范圍比較,它應該是索引中的最后一列。

不幸的是,這意味着你無法擺脫EXPLAIN計划中的“使用filesort”。 通常,如果您還在不同列上進行范圍比較,則無法使用索引優化排序。

但是你至少可以使用三列索引來縮小搜索范圍,這樣filesort就必須在一組較小的行上工作,然后它就可以在內存中完成。

另請參閱我的演示文稿如何設計索引,真的

如果要創建復合索引,那么在作為復合索引成員的各列上建立索引將是多余的。 確定您最常運行的查詢,查詢中涉及的每列的基數,查詢返回的大致行數,表中的總行數,是經常更新的表等。請記住索引插入和更新的成本。

目前最好的答案是最可怕的答案。 每次在EXPLAIN中看到“filesort”時,它都會非常慢,因為MySQL必須創建臨時文件並且不使用索引進行排序!

索引就像電話簿。 在您的情況下,正確的索引將是:

(col4,col1,col2,col3,primaryCol)

訂單很重要! 復合索引的最左側部分必須始終是您要排序的列。 然后,添加在WHERE子句中使用的其他列。 最后,對於MyISAM,您還需要添加主鍵(InnoDB會自動添加)。

此外,您需要更改查詢,以便分離/過濾和獲取完整的詳細信息:

SELECT * FROM `Table1` JOIN (
  SELECT primaryKey FROM  `Table1` 
  WHERE  `col1` =  '145307'
  AND  `col2` =  '0'
  AND col3 NOT 
  IN ( 130209, 130839 ) 
  ORDER BY col4 DESC 
  LIMIT 0 , 5
) foo ON Table1.primaryKey=foo.primaryKey

使用EXPLAIN進行檢查,您將看到正確的索引用法,用於排序和過濾。 然后,結果id再次與表(在另一個快速索引操作中)連接以獲取完整的詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM