0

[編集]

目標は、自己結合を使用して、シーケンシャル フィールド (sequentialsortfield) に基づいて特定の順序でフィールド (somevalue) の値を減算することです。そのままのクエリで正しい結果が得られますが、大規模なデータセットでは非常に遅くなります。mysql 'explain' を使用すると、このクエリがインデックスではなくファイルソートを使用していることがわかりますが、3 つの例のフィールドはすべてインデックス化されています。「order by」を削除すると、ファイルソートは使用されなくなりますが、目的の順序に関して正しい結果が得られません。

SOまたはMySQLのドキュメントを検索して、役に立ったものは何も見ませんでした。using filesortドロップしない限り、テーブル1で回避できないようですがorder by、必要です。インデックスは 3 つのフィールドすべてに存在します。

私の質問を説明するために例を生成しました。

「テーブル」の構造:

id                    INT  
somevalue             INT  
sequentialsortfield   INT  

クエリ:

select table1.somevalue-table2.somevalue as PrevRowDiff 
FROM table AS table1, 
table AS table2 
WHERE table1.sequentialsortfield+1 = table2.sequentialsortfield 
order by id;
4

2 に答える 2

0

このクエリを効率的にするのは、実際にはかなりトリッキーです。簡単に言うと、カバリング インデックスがある場合は、MySQL が主キーの順序でデータを出力するように強制するsequentialsortfield必要があります (これは結合を効率的にするために必要です)。

2 つの複合インデックスを作成し、そのうちの 1 つを暗黙的に強制することをお勧めします。

言う、

ALTER TABLE the_table ADD KEY the_one_to_force (id, sequentialsortfield, somevalue);
ALTER TABLE the_table ADD KEY usual_one (sequentialsortfield, somevalue);

クエリを次のように書き直します (この場合、ORDER BY は必要ありません)。

SELECT t1.somevalue-t2.somevalue as PrevRowDiff 
FROM the_table t1 FORCE INDEX (the_one_to_force)
JOIN the_table t2 ON t1.sequentialsortfield+1 = t2.sequentialsortfield

アイデアは、データがthe_one_to_forceインデックスの順序で読み取られ、一致する場合はデータが出力されるというものです (実際にはいずれにしても発生しますが、クエリに基づいて MySQL オプティマイザによって適切なインデックスが選択されます)。

于 2013-10-24T11:13:39.587 に答える