在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运行查询,有时会生成一个慢查询日志条目,有时不生成,即使在其他用户导致这样的行时继续生成它。
答案 0 :(得分:1)
首先取决于cond1
,然后取决于field1
和field2
在该条件下的基数:
如果cond1
涉及直接比较具有常量值的列(即索引可以帮助解决它),则可以使用field1
和/或field2
的复合索引帮助(见下文)。
如果cond1
涉及对列的操作 - 例如。应用函数或其他操作,例如my_int + 5 = 3
或DATE(my_timestamp) > NOW()
- 然后索引无法帮助;但请注意,这两个示例都可以重写为索引友好型:
my_int = 3 - 5
,显然相当于my_int = -2
;以及
my_timestamp >= CURDATE() + INTERVAL 1 DAY
。
只创建具有相对较高基数的索引(即可以快速区分许多记录),否则使用它将比全表扫描更好,同时减慢表写操作并消耗额外的存储空间记忆空间。不仅要考虑cond1
,field1
和field2
的基数,还要考虑cond1
和每个字段的基数。
假设它们都具有很高的基数,那么最好的办法是在(cond1, field1)
和(cond1, field2)
的每一个上实现index_merge
(union access)两个复合索引。