sql - 为什么当您使用 'IS' 而不是 '=' 时 SQLite 不使用索引?

标签 sql sqlite indexing

此查询不会使用索引: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 ,但我仍然很好奇为什么会出现这种情况。

最佳答案

无需支持此类查询的索引。

首先,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

对于 IS 运算符,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).

在你的问题中,

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)

其中括号内的表达式始终为 false,因此无用。

因此,ISIS NOT 仅在与 NULL 操作数一起使用时才有用。对于常规文字操作数,它与 = (或 !=)相同。并且 IS NULL 可以通过索引来满足。

关于sql - 为什么当您使用 'IS' 而不是 '=' 时 SQLite 不使用索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20114735/

相关文章:

Mysql将给定日期范围内的每日总计汇总为每周总计

sql - SQL如何检查记录是否存在?

SQLite - 使用随机唯一值更新

mysql - 设计这些表的最佳方式

c++ - SQLite C++ 'database is locked' 当多个进程以只读模式访问数据库时

c# - Finisar.SQLite.SQLiteException : SQL logic error or missing database: unrecognized token: "$"

c# - 在列表中查找匹配了三个项目的元组

python - 如何创建一个组合嵌套在元组中的列表值的索引?

python - NumPy Fancy Indexing - 从不同 channel 裁剪不同的 ROI

php - 征信系统如何防范欺诈?