This query will not use the index: SELECT * FROM baz WHERE id IS '123'
http://sqlfiddle.com/#!7/7e299/2
This query will use the index: SELECT * FROM baz WHERE id='123'
http://sqlfiddle.com/#!7/7e299/1
Why??
EDIT: I realize there is the stupid answer of expanding the IS to get the correct effect (ie making the query SELECT * FROM baz WHERE id='123' OR '123' IS NULL
, but I am still curious why this is the case.
There's no need to support indexing for such queries.
First, that's just how the query optimizer works :
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
For the IS
operator, NULL
values are special :
The IS and IS NOT operators work like = and != except when one or both of the operands are NULL. In this case, if both operands are NULL, then the IS operator evaluates to 1 (true) and the IS NOT operator evaluates to 0 (false). If one operand is NULL and the other is not, then the IS operator evaluates to 0 (false) and the IS NOT operator is 1 (true).
In your question,
SELECT * FROM baz WHERE id IS '123'
and
SELECT * FROM baz WHERE id='123' OR id IS NULL
are not the same thing. (The latter can be satisfied using two index lookups.) It should be something like
SELECT * FROM baz WHERE id='123' OR (id IS NULL AND '123' IS NULL)
where the parenthesized expression is always false and therefore useless.
So IS
and IS NOT
is really only useful when used with NULL
operand. With regular literal operand it is the same as =
(or !=
). And IS NULL
can be satisfied by an index.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.