我有这样的查询:
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/