在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,然后取决于在这种情况下field1field2的基数:


如果cond1涉及直接比较具有常量值的列(即索引可以帮助解析它),则具有field1和/或field2的复合索引可能会有所帮助(请参见下文)。

如果cond1涉及对列的操作,例如应用函数或其他操作(例如my_int + 5 = 3DATE(my_timestamp) > NOW()),那么索引将无济于事;但是,请注意,这两个示例都可以重写为对索引友好的:


my_int = 3 - 5,显然等同于my_int = -2;和
my_timestamp >= CURDATE() + INTERVAL 1 DAY

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

假设它们都具有高基数,那么最好的选择是在index_merge(cond1, field1)上分别使用两个复合索引来实现(cond1, field2) (union access)

08-07 17:15