我有这样的查询:
DELETE FROM events WHERE type = 4 AND author_id IN (?, ?) AND post_id IN (?, ?)
如您所知,author_id IN (? , ?)
转换为author_id = ? OR author_id = ?
。那么我应该在author_id
列上创建索引吗?
事实上,我正在尝试理解MySQL在它们之间存在OR
时如何处理条件。我在某处读到了这句话:
MySQL遇到
OR
时似乎忽略了索引。
但我无法理解它的含义。有人可以吗?总的来说,上面的查询需要哪些索引?
答案 0 :(得分:2)
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
输出以查看是否可以。)
相反,它会选择它认为最有效的索引,使用它来查找与条件的那部分匹配的行,并扫描这些行以评估剩余条件。