[英]Why does SQLite not use indexes when you use 'IS' instead of '='?
该查询将不使用索引: SELECT * FROM baz WHERE id IS '123'
http://sqlfiddle.com/#!7/7e299/2
该查询将使用索引: SELECT * FROM baz WHERE id='123'
http://sqlfiddle.com/#!7/7e299/1
为什么??
编辑:我意识到存在扩展IS以获得正确效果的愚蠢答案(即使查询SELECT * FROM baz WHERE id='123' OR '123' IS NULL
,但是我仍然很好奇为什么是这种情况。
无需支持为此类查询建立索引。
首先,这就是查询优化器的工作方式 :
To be usable by an index a term must be of one of the following forms:
column = expression
column > expression
column >= expression
column < expression
column <= expression
expression = column
expression > column
expression >= column
expression < column
expression <= column
column IN (expression-list)
column IN (subquery)
column IS NULL
对于IS
运算符, NULL
值是特殊的 :
IS和IS NOT运算符的工作方式类似于=和!=,除非其中一个或两个操作数均为NULL。 在这种情况下,如果两个操作数均为NULL,则IS运算符的计算结果为1(true),而IS NOT运算符的计算结果为0(false)。 如果一个操作数为NULL而另一个操作数为NULL,则IS运算符的计算结果为0(假),而IS NOT运算符的计算结果为1(真)。
在你的问题上
SELECT * FROM baz WHERE id IS '123'
和
SELECT * FROM baz WHERE id='123' OR id IS NULL
是不一样的东西。 (可以使用两个索引查找来满足后者。)应该类似于
SELECT * FROM baz WHERE id='123' OR (id IS NULL AND '123' IS NULL)
括号表达式始终为假,因此无用。
因此, IS
和IS NOT
实际上仅在与NULL
操作数一起使用时才有用。 使用常规文字操作数时,它等于=
(或!=
)。 索引可以满足IS NULL
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.