0

在 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 运行查询,有时会生成缓慢的查询日志条目,有时不会生成,即使当其他用户导致此类行时仍会继续生成。

4

1 回答 1

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. 只值得创建具有相对较高基数的索引(即可以快速区分许多记录),否则使用它会比全表扫描好一点,同时减慢表写入操作并消耗额外的存储和内存空间。不仅要考虑和的基数cond1,还要考虑与每个域一起的基数。field1field2cond1

    假设它们都具有高基数,您最好的选择是实现一个index_merge(联合访问)(cond1, field1) ,每个和都有两个复合索引(cond1, field2)

于 2012-11-11T23:17:03.873 回答