mysql - 当条件之间存在OR时,我应该如何创建索引?

标签 mysql sql

我有这样的查询:

DELETE FROM events WHERE type = 4 AND author_id IN (?, ?) AND post_id IN (?, ?)

如您所知,author_id IN (?, ?) 转换为 author_id = ?或者 author_id = ?。那么我应该在 author_id 列上创建索引吗?

事实上,当它们之间存在 OR 时,我试图了解 MySQL 如何处理条件。我在某处读到这句话:

MySQL seems to ignore indices once it encounters an OR.

但是我不明白它的意思。任何人都可以吗?总体而言,上面的查询需要哪些索引?

最佳答案

的确,OR 通常会阻止索引的有效使用。在处理 WHERE 子句时,查询通常只能对每个表使用一个索引。所以如果你有这样的情况

WHERE col1 = 1 OR col2 = 2

它不能使用任何单个索引来查找所有匹配的行。通常最好将查询分成两部分并使用 UNION:

SELECT ...
FROM TABLE
WHERE col1 = 1
UNION
SELECT ...
FROM TABLE
WHERE col2 = 2

但是,我想我在某处读到过,在简单的情况下,MySQL 能够自动执行此转换。检查查询的 EXPLAIN 输出。

但是当OR条件涉及到相同的列时,它仍然可以使用索引,例如如果你有

WHERE col1 = 1 OR col1 = 2

它只需在 col1 的索引中查找这两个索引条目。这就是它在您编写时所做的事情:

WHERE col1 IN (1, 2)

但是,您的查询比这更复杂,因为它还用 AND 组合了多个条件。如果您只是使用 = 比较,它可以使用多列索引对其进行优化,例如

INDEX (type, author_id, post_id)

但是当你有多个 IN 条件时,就不能这样做了,因为它需要枚举所有的组合。

type = 4 AND author_id IN (1, 2) AND post_id IN (10, 20)

需要查找所有这些索引:

4, 1, 10
4, 1, 20
4, 2, 10
4, 2, 20

我不认为 MySQL 会生成所有这样的组合(但我可能是错的——检查 EXPLAIN 输出以查看它是否可以)。

相反,它将选择它认为最有效的索引,使用它来查找与该部分条件匹配的行,并扫描这些行以评估其余条件。

关于mysql - 当条件之间存在OR时,我应该如何创建索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37712772/

相关文章:

html - 一些 html 标签在 jasper 报告中不起作用

mysql - 查询以获取所有用户 Y 的兴趣主题,其中 Y 与用户 X 共享 >=3 个兴趣

sql - 将 WHERE 条件转换为 LEFT JOIN

mysql - 连接2个表的SQL查询

mysql - Ruby dbi mysql 连接

php - 使用php从mysql中仅以日期格式选择年份

使用两个输入字段的 PHP 搜索引擎

java - 如何加快以下 JDBC 插入/导入过程?

c# - 在 SqlConnection.Open()、asp.net 上未将对象引用设置为对象的实例

mysql - 从 INFORMATION_SCHEMA COLUMNS 表构建列定义