在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运行查询,有时会生成缓慢的查询日志条目,有时不会生成,即使在其他用户引起此类行时仍会继续生成查询条目。
最佳答案
它首先取决于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
的基数以及每个字段。
假设它们都具有高基数,那么最好的选择是在index_merge
和(cond1, field1)
上分别使用两个复合索引来实现(cond1, field2)
(union access)。