[英]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
上面的每列上都有一個單獨的索引( col1
到col4
)。
編輯 :
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.