2016-11-10 22 views
0

私はinnodbテーブルを持っています。テーブルのクエリは以下のようになります。MySQL Innodbは、間違った行見積りのためにインデックスを使用できません。

SELECT * 
FROM x 
WHERE now() BETWEEN a AND b 

テーブル内の行の総数は700Kの周囲にいる間、私は上の複合インデックスを作成しました(a、b)は、クエリは約4K行を返します。

ただし、実行計画のEXPLAINを取得すると、クエリで期待されたインデックスが使用されていないことがわかりました。 rowsは360Kと推定されるため、実際の値よりも非常に大きくなります。

私はちょうど多くの記事(Why the rows returns by "explain" is not equal to count()?のような)が説明したように知っています、EXPLAINはおおよその見積もりを取得します。しかし、FORCE INDEXソリューションは非常に扱いにくく、今後、パフォーマンス上のリスクが生じる可能性があります。

MySQLをより正確な見積もりにする方法はありますか(現在のものは90倍です)。ありがとう。

+0

いいえ、インデックスが役に立たないため、インデックスを使用できません。テーブルをスキャンする方が効率的です。 –

答えて

0

InnoDBはテーブルの行数を近似的に保持します。これはSHOW TABLE STATUSの文書で説明されています。

行の数を。 MyISAMなどの一部のストレージエンジンは、正確なカウントを格納します。 InnoDBなどの他のストレージエンジンの場合、この値は近似値であり、実際の値と40〜50%程度異なる場合があります。

InnoDBに正確な行数を保存させる方法はないと思います。

WHERE constant BETWEEN col1 AND col2 

ませんMySQLのインデックス

は、それが高速に実行するために考案することができます。

+0

お返事ありがとうございます。テーブルを小さなテーブルに分割しないと、クエリを高速化する唯一の方法は 'FORCE INDEX'ですか?私の心配は、将来的にデータの配布やインデックスが変更された場合、 'FORCE INDEX'の影響を認識していない可能性があるということです。インデックスを手動で選択するのは難しいことです。 – twds

+0

私は本当にそれを研究していないので、私はそれに答えることはできません。 – Barmar

+0

私は、クエリの最適化への影響が正確なカウントを維持するという問題を解決するのに十分なほど大きくないと判断しています。 – Barmar

0

この特定の構築物を最適化することは困難です。試みは、次のとおりです。

INDEX(col1) -- will scan last half of table 
INDEX(col2) -- will scan first half of table 
INDEX(col1, col2) -- will scan last half of table 

は、(それがインデックスB木での作業の多くを行いますかどうかはどのような場合には、行の多くは触れなければなりません、などしかし、カバー、ICPによって異なります。)

ワンそれが改善できない理由は、 '半分'の '最後の'行が実際に一致する可能性があるということです。

(col1、col2)のペアが重複しない場合は、1つの行の後で停止できるため、パフォーマンスが向上する可能性があります。しかし、MySQLはあなたがこのケースを持っているかどうかわからないので、最適化することはできません。 Hereは、重複しない方法です効率的なIPアドレスルックアップ。

関連する問題