2
SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY SourceId, ExternalProductId
HAVING cnt > 1

(ExternalProductId、SourceId、AnotherField) にインデックスがあります。Explain は、索引が使用されていることを示しています。これは、説明の「追加」列に出力されます。

Using where; Using index; Using temporary; Using filesort

クエリを実行すると、SHOW PROCESSLIST で次のように表示されます。

Copying to tmp table on disk

このクエリを微調整して、インデックスで機能するようにすることはできますか? 他のプロセスがこのテーブルで同時に作業しているために、取得した結果が多少不正確であっても構いません。分離レベルを変更して、クエリのパフォーマンスを向上させることはできますか?

4

2 に答える 2

3

複合インデックスの最初の 2 つのフィールドの順序に対応するように列を逆GROUP BYにすると、複合インデックスがより効果的に使用されます。

SELECT COUNT(*) AS cnt
FROM products
WHERE ExternalProductId IS NOT NULL
GROUP BY ExternalProductId, SourceId
HAVING cnt > 1

クエリ実行プレーンは になり'Using where; Using index'、他の によって引き起こされた一時テーブルとファイルソートの両方を取り除く必要がありGROUP BYます。

同じ結果が得られますが、順序が少し異なります。

于 2010-12-16T18:25:52.750 に答える
0

試してみるいくつかのこと:

  1. MySQL は group by で自動的にソートします。ソート順を気にしない場合は、'ORDER BY NULL' 句を追加します。これにより、ファイルソートとおそらく一時テーブルが削除されます。

  2. カウント (*) を削除し、ワイルドカードの代わりにインデックス内の列の名前を使用します。

また。あなたの指標は何ですか?完全なテーブル作成ステートメントを表示できますか?

于 2010-12-16T15:35:16.733 に答える