假设我有一个带有列的表,其中取值为1到10.我需要选择除9和10之外的所有值的列。使用此查询时是否存在差异(性能方面):
SELECT * FROM tbl WHERE col NOT IN (9, 10)
和这一个?
SELECT * FROM tbl WHERE col IN (1, 2, 3, 4, 5, 6, 7, 8)
答案 0 :(得分:12)
使用“IN”,因为它很可能使DBMS在相应列上使用索引。
“NOT IN”理论上也可以转换为索引用法,但是以更复杂的方式,DBMS可能不会“花费开销时间”使用。
答案 1 :(得分:10)
在性能方面,您应该始终对代码进行分析(即运行您的查询数千次,并使用某种stopwatch
Sample来衡量每个循环的性能。
但在这里我强烈建议使用第一个查询以便更好地保存未来。逻辑是你需要除9和10之外的所有记录。如果你在表中添加值11并使用第二个查询,那么应用程序的逻辑将被破坏,当然会导致错误。
编辑:我记得这被标记为php,这就是我在php中提供示例的原因,但我可能会弄错。我想用你正在使用的语言重写那个样本并不难。
答案 2 :(得分:3)
我已经看到Oracle在使用NOT IN优化某些查询时遇到问题,如果列可以为空。如果您可以以任何方式编写查询,就我而言,IN是首选。
答案 3 :(得分:1)
对于常量列表,MySQL将在内部将代码扩展为:
SELECT * FROM tbl WHERE ((col <> 9 and col <> 10))
另一个相同,而=
代替8次。
所以是的,第一个会更快,更少的比较。可测量的机会可以忽略不计,与解析SQL和检索数据的一般开销相比,少数常量比较的开销无关紧要。
答案 4 :(得分:0)
“ IN”语句在内部就像一系列“ OR”语句一样工作。
例如:
SELECT * FROM tbl WHERE col IN (1, 2, 3)
等于
SELECT * FROM tbl WHERE col = 1 OR col = 2 OR col = 3
“ OR”语句可能会导致一些性能问题,如本文所述: https://bertwagner.com/2018/02/20/or-vs-union-all-is-one-better-for-performance/
当您执行NOT IN语句时,它们完全相同,但是结果有逻辑上的拒绝。但是,您可以在性能上更好地编写和进行等效查询。在您的示例中:
SELECT * FROM tbl WHERE col NOT IN (9, 10)
等于
SELECT * FROM tbl WHERE col <> 9 AND col <> 10
使用“ AND”语句,当所有条件之一都为假时,数据库停止分析,因此,其性能要比“ IN”语句中使用的“ OR”好得多。