在sqlite3中,`select * from myTable where 1=0` -它会跳过表扫描吗?

d7v8vwbk  于 2023-06-23  发布在  SQLite
关注(0)|答案(1)|浏览(132)

给定查询:

  • select * from myTable where 1=0

如果我这样做:

  • explain query plan <above_query>

它说:

  • > scan table myTable

这是真的吗它是否真的会执行表扫描(即扫描表中的每一行)?或者它是否实际上跳过table-scan并立即返回一个空的结果集,因为给定的where clause永远不会计算为true

pprl5pva

pprl5pva1#

Sqlite准备了一个带有表扫描的计划,但它实际上跳过了整个扫描。如果你执行

explain select * from myTable where 1=0;

你会得到这个编译的计划:

addr  opcode         p1    p2    p3    p4             p5  comment      
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     9     0     NULL           0   Start at 9
1     Ne             2     8     1     NULL           80  if r[1]!=r[2] goto 8
2     OpenRead       0     2     0     2              0   root=2 iDb=0; t
3     Rewind         0     8     0     NULL           0   NULL
4       Column         0     0     3     NULL           0   r[3]= cursor 0 column 0
5       Column         0     1     4     NULL           0   r[4]= cursor 0 column 1
6       ResultRow      3     2     0     NULL           0   output=r[3..4]
7     Next           0     4     0     NULL           1   NULL
8     Halt           0     0     0     NULL           0   NULL
9     Transaction    0     0     1     0              1   usesStmtJournal=0
10    Integer        1     1     0     NULL           0   r[1]=1
11    Integer        0     2     0     NULL           0   r[2]=0
12    Goto           0     1     0     NULL           0   NULL

它将跳转到第9行,设置事务并将0和1加载到两个寄存器中,然后跳回到第1行。然后,它将比较两个寄存器,发现两个值不同,它将跳到第8行并停止,甚至不打开表。
Sqlite没有优化到知道1=0永远不会计算为true,但它确实意识到表达式不依赖于表的任何列,因此它只对整个SELECT计算一次,而不是对每行。

相关问题