3つの列(ドイツのバイグラム)を含む1GBの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 Explainは、まだファイルソートを使用していることを教えてくれます!
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));
ターゲットフィルターがファイルソートを生成するため、オプションではありません。そうでない場合、プレフィックスが長く、ソースが一般的な単語である場合、トラバースする必要のある要素の結果リストが非常に長くなる可能性があります。
私はどういうわけかこれに対する明白な解決策がないと感じていますか?