[英]Optimizing my mysql query to use index for sorting
我有一個基於3列的復合索引,其中兩列在我的查詢中受約束,第三列是按順序子句,但mysql不使用索引進行排序。
explain select * from videos where public_private='public' and approved='yes' order by number_of_views desc; +----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+ | 1 | SIMPLE | videos | ALL | approved,approved_3,approved_2 | NULL | NULL | NULL | 1476818 | Using where; Using filesort | +----+-------------+--------+------+--------------------------------+------+---------+------+---------+-----------------------------+
表結構如下:
CREATE TABLE `videos` (
`indexer` int(9) NOT NULL auto_increment,
`user_id` int(9) default NULL,
`public_private` varchar(24) default NULL,
`approved` varchar(24) default NULL,
`number_of_views` int(9) default NULL,
PRIMARY KEY (`indexer`),
KEY `approved` (`approved`,`user_id`),
KEY `approved_3` (`approved`,`public_private`,`indexer`),
KEY `approved_2` (`approved`,`public_private`,`number_of_views`),
) ENGINE=MyISAM AUTO_INCREMENT=1969091 DEFAULT CHARSET=utf8 |
我該怎么做才能強制mysql使用索引來對結果進行排序?
我相信你的查詢可能匹配表中大部分數據。 在這種情況下,MySQL優化器通常選擇進行表掃描並完全忽略索引,因為它實際上比通過額外讀取整個索引並使用它來挑選數據的麻煩更快。 所以在這種情況下,我猜測public_private='yes' and approved='yes'
匹配你桌子的很大一部分。 因此,如果MySQL因此而跳過使用索引,那么它也不能用於排序。
如果你真的希望它使用索引,那么解決方案是使用FORCE INDEX
:
select * from videos FORCE INDEX (approved_2) where public_private='public' and approved='yes' order by number_of_views desc;
但是,我會運行一些測試來確保您獲得的內容實際上比MySQL優化器選擇的更快。 顯然,優化器在選擇訂購方面確實存在一些問題 ,所以你絕對可以試一試,看看你是否獲得了改進的性能。
訂單在復合鍵中很重要。 如果您想使用approved_2
密鑰對number_of_views
進行排序,請更改:
KEY `approved_2` (`approved`,`public_private`,`number_of_views`)
至:
KEY `approved_2` (`number_of_views`,`approved`,`public_private`)
MySQL中的復合鍵從左到右工作。 在上面的示例中,使用number_of_views
, approved
和public_private
implicity聲明的鍵創建索引:
number_of_views
number_of_views
, approved
number_of_views
, approved
, public_private
這應該工作:
`select * from videos where approved='yes' and public_private='public' order by number_of_views desc;`
如果沒有,只需在number_of_views
上創建一個單獨的索引。
這必須奏效。
(mysql基本上遵循左右序列。因此,如果未在此序列中使用,則您對approved
public_private
, number_of_views
索引將不起作用。即,您可以使用左側的所有三個,左側的2個或最左側的1.但它贏了如果你不使用最左邊的那個就行了,那就是這個想法。)
使用單獨的索引會自動對number_of_views
進行排序,這可能有助於按order by
- 但我確信這一點。
訂單在復合鍵中很重要。 我忘了規則,但嘗試不同的順序。
在number_of_views
列上添加單獨的索引,然后查看它是否有效。
如果一個鍵是3列的組合,它將僅在使用全部3個鍵執行操作時才使用該特定鍵
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.