このクエリ:
SELECT *
FROM listings
WHERE (publishedon BETWEEN 1441105258 AND 1443614458) AND
(published = 1) AND
(cat_id in (1,2,3,4,5)) AND
(source_id in (1,2,3,4,5));
インデックスだけで最適化するのは難しいです。最適なインデックスは、published
で始まるインデックスです。 そして、他の列があります-それらの順序がどうあるべきかは明確ではありません。その理由は、published
以外のすべてが =
を使用していません 。
パフォーマンスの問題はある種のものであるため、多くの行が返されていることを示しています。通常、インデックスはWHERE
を満たすために使用されます インデックスの前の句をORDER BY
に使用できます 。そのため、これを最適化するのは困難です。
提案。 。 。それほど素晴らしいものはありません:
- 月ごとにデータにアクセスする場合は、月ごとにデータを分割することを検討してください。これにより、
ORDER BY
なしでクエリが作成されます 高速ですが、ORDER BY
には役立ちません 。 published
後にさまざまな順序の列を試してください インデックスで。最も選択的な列が見つかる場合があります。ただし、これもソート前のクエリを高速化します。-
WHERE
でより多くの等式条件を持つようにクエリを構造化する方法を考えてください または、より小さなデータセットを返します。 - (あまりお勧めしません)
published
にインデックスを付けます と注文列。次に、サブクエリを使用してデータをフェッチします。不等式条件を設定します(IN
など)外部クエリで。サブクエリは、インデックスを使用して並べ替え、結果をフィルタリングします。
最後のものが推奨されない理由は、SQL(およびMySQL)がサブクエリからの結果の順序を保証しないためです。ただし、MySQLはサブクエリを実体化するため、結果は実際に正常です。バージョンごとに変わる可能性のある、文書化されていない副作用を使用するのは好きではありません。