多年来我一直在寻找如何使用索引进行这样的查询。
SELECT * FROM aliens_tmp
WHERE creator != 'a'
AND COUNTRY = 'UK'
ORDER BY id DESC LIMIT 0, 10
无论我创建什么索引都不会成功,因为 != 与索引的包容性冲突。
所以我想在我做类似的事情的地方做一个减号
SELECT * FROM aliens_tmp
WHERE COUNTRY = 'UK
MINUS
SELECT * FROM aliens_tmp
WHERE CREATOR = 'a'
ORDER BY id DESC LIMIT 0, 10
...但是 MINUS 不存在。所以我看了看,认为我可以使用 http://www.bitbybit.dk/carsten/blog/?p=71 上提到的老把戏。简而言之就是
SELECT DISTINCT a.member_id, a.name
FROM a LEFT JOIN b USING (member_id, name)
WHERE b.member_id IS NULL
但这并不能帮助我实现最初的目标,即在保持使用索引的同时进行减号,因为任何连接到我自己的表仍然必须排除我的创建者,这会导致未命中,因为排除有什么想法吗?
最佳答案
如果您的表的大部分由具有 creator != 'a'
的行组成,那么使用索引不会给您带来任何优势。但是,如果您的大部分行都带有 creator='a'
,那么您可以考虑将这些值分配给 creator(或使用枚举),如果您按 creator 'a' 排序,则排在第一位。您可以使用 creator > 'a'
条件,而不是检查 creator != 'a'
,这非常适合使用 btree 索引。
更新有关创作者的更多信息:
因此您的 creator != 'a'
条件的选择性极低,尝试对 creator 使用索引毫无意义。您正在限制您的结果并按 id desc 排序,因此应该使用 country 上的键返回尽可能少的行,方法是简单地检查从最高 id 开始的每一行是否满足 where 条件,直到有足够的限制。如果您在 explain select ...
中看到键:国家和行数接近 10,它不会变得更快。
关于mysql - 如何在仍然使用索引的同时在 MySQL 中执行与 MINUS 相同的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6141378/