where句に次がある場合:
( approps_precio * moneda_valor BETWEEN 2000 AND 6000)
idx_appprops_precio インデックスは使用しません。
しかし
( approps_precio BETWEEN 2000 AND 6000)
とてもうまくやってくれます。
* 操作を追加してもインデックスを使用する方法はありますか?
前もって感謝します。
moneda_valor
定数ですか?そうでない場合approps_precio
、approps_precio に moneda_valor を掛けた値を探すときに、上のインデックスは役に立ちません。
Paul DuBois (MySQL ドキュメンテーション チームのメンバーではありますが) が彼の著書MySQL (Developer's Library)の第 5 章「クエリの最適化」で述べていることをサポートするために、いくつかの公式ドキュメントを探し回っています。
比較式で索引付けされた列を独立させます。関数呼び出しで列を使用する場合、または算術式のより複雑な項の一部として列を使用する場合、MySQL はすべての行の式の値を計算する必要があるため、インデックスを使用できません。これは避けられない場合もありますが、多くの場合、クエリを書き直して、インデックス付きの列が単独で表示されるようにすることができます。
私が見つけることができる最高のものは、Internals マニュアルのOptimizer Transpositionsに関するセクションです。
ただし、MySQL は算術演算が存在する転置をサポートしていません。したがって:
WHERE 5 = -column1
は次のものと同じには扱われません:
WHERE column1 = -5
column = constant の形式の式への転置は、インデックス検索に最適です。
この場合、 でapprops_precio
除算してフィルタ条件を書き直すことで、インデックス on を利用できmoneda_valor
ます。
WHERE approps_precio BETWEEN 2000/moneda_valor AND 6000/moneda_valor
MySQL は引き続き各レコードの除算を評価する必要があることに注意してください。
* 操作は値を 0 にするため、moneda_valor が null の場合は範囲外になります。したがって、次のように書き換えることができます。
approps_precio BETWEEN 2000 AND 6000 and moneda_valor IS NOT NULL