8

私は2200万のレコードを持つ大きなテーブルを持っています。次のクエリを実行したい:

select auto_alerts from alerts_stat  where endDate > "2012-12-01"

パフォーマンスを向上させるために、endDataフィールドにBTREEインデックスを追加しました。

CREATE INDEX endDate_index USING BTREE ON alerts_stat(endDate)

クエリ実行プランの分析を開始した後:

今から15〜7日前のパラメータを取得したい場合:

explain select alerts_sp from alerts_stat 
where endDate between CURDATE() - 15 and CURDATE() - 7;

次の実行プランで2,762,088行を処理しました。

'1', 'SIMPLE', 'browser_plugin_alerts_stat', 'range', 'endDate_index', 'endDate_index', '4', NULL, '2762088', 'Using where'

間隔を1日増やすと、次のようになります。

explain select alerts_sp from alerts_stat 
where endDate between CURDATE() - 15 and CURDATE() - 6;

EXPLAINによると、MySQLは22,923,126行すべてを処理する予定です。

'1', 'SIMPLE', 'browser_plugin_alerts_stat', 'ALL', 'endDate_index', NULL, NULL, NULL, '22932390', 'Using where'

たとえば、WHEREプロセス22,925,642で条件なしで選択します。

実行計画を改善してもいいですか?たぶん私はどこかで間違いを犯しているのでしょうか、それとも通常のMySQLの振る舞いですか?

4

1 に答える 1

3

結果セットが全行の 8 ~ 9% を超えると、MySQL は完全なテーブル スキャンを実行します。私には、ある日、スイング MySQL をフル テーブル スキャン方向に追加するように見えます。結果がより良いかどうかを確認するためにインデックスを強制してみてください。

アップデート:

私が読んだことから、MySQL クエリ オプティマイザーは、このような境界線上のケースでは間違った選択をする傾向があるため、インデックスを強制する方が簡単にうまくいく可能性があります。それ以外の場合、これは単純なクエリであり、最適化の余地はあまりありません。

おそらく、これら 2 つの列にカバリング インデックスを作成し、その使用を強制すると、最良の結果が得られる可能性があります。

于 2012-12-21T13:29:22.917 に答える