![](/img/trans.png)
[英]How to design an index/query to avoid filesort in a simple MySQL query?
[英]How to avoid a filesort on a mysql composite index for a prefix query with an order by statement?
我有一個帶有三個列(德語雙峰)的1 GB mysql表:
create table sortedindex (source varchar(60),target varchar(60),score float)
engine=myisam character set utf8 collate utf8_bin;
我還創建了一個復合索引:
create index sortedstd_ix on sortedindex (source(60), target(60), score);
另外,我壓縮了表並使其變為只讀,並使用以下方法對索引進行了排序:
myisamchk --keys-used=0 -rq sortedindex
myisampack sortedindex
myisamchk -rq sortedindex --sort_buffer=3G --sort-index --sort-records=1
現在,我問具有以下結構的查詢:
如下所示:
select * from sortedindex where source like "ein" and target like "interess%" order by score desc limit 5;
mysql解釋告訴我,仍然使用文件排序!
mysql> explain select * from sortedindex where source like "ein" and target like "interess%" order by score desc limit 5;
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+------------------------------------------+
| 1 | SIMPLE | sortedindex | range | sortedstd_ix | sortedstd_ix | 366 | NULL | 17 | Using where; Using index; Using filesort |
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+------------------------------------------+
1 row in set (0.00 sec)`
我了解如果將查詢更改為:
explain select * from sortedindex where source like "ein" and target like "interess%" order by source, target, score desc limit 5;
不會有文件排序,但是會出錯,涉及到文件排序。
mysql> explain select * from sortedindex where source like "ein" and target like "interess%" order by source, target, score desc limit 5;
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+------------------------------------------+
| 1 | SIMPLE | sortedindex | range | sortedstd_ix | sortedstd_ix | 366 | NULL | 17 | Using where; Using index; Using filesort |
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+------------------------------------------+
1 row in set (0.00 sec)
通過這次討論,我意識到desc關鍵字是問題所在。 因此我們不檢查:
mysql> explain select * from sortedindex where source like "ein" and target like "interess%" order by source, target, score limit 5;
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+--------------------------+
| 1 | SIMPLE | sortedindex | range | sortedstd_ix | sortedstd_ix | 366 | NULL | 17 | Using where; Using index |
+----+-------------+-------------+-------+---------------+--------------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
完美的工作。
但是我想要對分數而不是目標進行降序排序。 以這種方式創建索引
create index sortedstd_ix on sortedindex (source(60), score desc, target(60));
這不是一個選擇,因為目標過濾器將產生文件排序,否則,如果前綴很長並且source是一個常用詞,則需要遍歷的元素的結果列表可能會很長。
我以某種方式感覺沒有明顯的解決方案?
嘗試這個 ::
select * from sortedindex
where source like "ein" and target like "interess%"
order by score desc, source, target limit 5;
你是對的。 沒有明顯的解決方案。 需要排序是因為您要查詢目標的多個值(例如“ interess%”)。 因此,索引不會為您提供按分數排序的行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.