如果我在 where 子句中有以下内容:
( approps_precio * moneda_valor BETWEEN 2000 AND 6000)
它不使用 idx_appprops_precio 索引。
但
( approps_precio BETWEEN 2000 AND 6000)
做得很好。
有没有办法添加 * 操作并仍然使用索引?
提前致谢。
是moneda_valor
常数吗?如果不是,approps_precio
则当您查找 appprops_precio 乘以 moneda_valor 的值时,索引是无用的。
我一直在寻找一些官方文档来支持 Paul DuBois(尽管是 MySQL 文档团队的成员)在他的书MySQL(开发人员库)的第五章“查询优化”中所说的话:
使索引列在比较表达式中独立。如果您在函数调用中使用列或作为算术表达式中更复杂术语的一部分,MySQL 将无法使用索引,因为它必须为每一行计算表达式的值。有时这是不可避免的,但很多时候您可以重写查询以使索引列自行出现。
我能找到的最好的是内部手册中关于优化器转置的部分:
但是,MySQL 不支持存在算术的转置。因此:
WHERE 5 = -column1
不被视为相同:
WHERE column1 = -5
转换为 column = constant 形式的表达式是索引查找的理想选择。
在这种情况下,可以approps_precio
通过除以重写过滤条件来利用索引moneda_valor
:
WHERE approps_precio BETWEEN 2000/moneda_valor AND 6000/moneda_valor
请注意,MySQL 仍然需要评估每条记录的划分,所以我不相信会节省多少。
* 操作使您的值变为 0,因此当 moneda_valor 为空时超出范围。因此,您可以将其重写为:
approps_precio BETWEEN 2000 AND 6000 and moneda_valor IS NOT NULL