1

我有三個colums(德國雙字母組)1 GB的MySQL表:如何使用order by語句避免前綴查詢的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); 

額外的I壓縮表,並使其只讀和排序使用索引:

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的解釋告訴我,仍然是使用filesort!

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) 

from this discussion我意識到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)); 

創建索引不是因爲目標過濾器的選項將一個文件產生某種然後,或者如果不是需要遍歷可真夠長的,如果前綴爲元素的結果列表長和源是一個常用詞。

我不知何故有沒有明顯的解決辦法呢?

回答

0

你是對的。對此沒有明顯的解決方案。需要排序是因爲您要求多個目標值(如「interess%」)。因此,索引不會給你按照分數排序的行。

+0

如果你沒有提供解決方案,我必須發表評論的問題,而不是回答 –

+0

這個答案是絕對正確的,並提供了我的問題的答案 –

0

試試這個::

select * from sortedindex 
where source like "ein" and target like "interess%" 
order by score desc, source, target limit 5; 
+0

解釋說,它仍然在使用文件排序,我實際上是在閱讀您的答案時所期望的。排序字段的順序必須遵守索引創建的順序。 http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes。html –