簡體   English   中英

如何避免在MySQL綜合索引上使用order by語句進行前綴查詢的文件排序?

[英]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

現在,我問具有以下結構的查詢:

  • 修復源
  • 指定目標的前綴
  • 按分數檢索前k行

如下所示:

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.

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