MySQL优化提示DNF

时间:2012-11-11 23:12:00

标签: mysql sql optimization

在MYSQL中,一些我不想改变太多的Wordpress插件代码运行以下查询:

SELECT * WHERE cond1 AND (field1 = val1 OR field2 = val2)

然而,尽管val1和val2上有索引,但它的运行速度非常慢。 (慢速查询日志确认它会扫描所有行。)我是否可以提示MYSQL它应该始终将公式扩展为以下等效但更快的形式?

SELECT * WHERE cond1 AND (field1 = val1)
UNION
SELECT * WHERE cond1 AND (field2 = val2)

这会大大减少扫描的行数,因此会产生非常优越的性能。

我也有同样的想法
SELECT * WHERE cond1 AND (field1 in (val1, val2))

谢谢!

修改:有关该表的一些信息和查询说明位于http://pastebin.com/Qd1ZaVKD,但似乎不一致。如果我从myphpadmin运行查询,有时会生成一个慢查询日志条目,有时不生成,即使在其他用户导致这样的行时继续生成它。

1 个答案:

答案 0 :(得分:1)

首先取决于cond1,然后取决于field1field2在该条件下的基数:

  1. 如果cond1涉及直接比较具有常量值的列(即索引可以帮助解决它),则可以使用field1和/或field2的复合索引帮助(见下文)。

    如果cond1涉及对列的操作 - 例如。应用函数或其他操作,例如my_int + 5 = 3DATE(my_timestamp) > NOW() - 然后索引无法帮助;但请注意,这两个示例都可以重写为索引友好型:

    • my_int = 3 - 5,显然相当于my_int = -2;以及

    • my_timestamp >= CURDATE() + INTERVAL 1 DAY

  2. 只创建具有相对较高基数的索引(即可以快速区分许多记录),否则使用它将比全表扫描更好,同时减慢表写操作并消耗额外的存储空间记忆空间。不仅要考虑cond1field1field2的基数,还要考虑cond1和每个字段的基数。

    假设它们都具有很高的基数,那么最好的办法是在(cond1, field1)(cond1, field2)的每一个上实现index_merge (union access)两个复合索引。