WHERE 子句中的 SQLite 计算列似乎有效(?)
SQLite computed column in WHERE clause seems to be working(?)
DMBS 执行查询的顺序是:
FROM -> JOIN -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> LIMIT
我惊讶地发现这个查询在 SQLite 上运行良好:
SELECT *, duration / 60 AS length_in_hours
FROM movies
WHERE length_in_hours > 10;
为什么这个查询有效,而在某些 other cases 中它似乎失败了?
好的,所以我 运行 EXPLAIN
看看这里发生了什么。
.eqp full
PRAGMA vdbe_trace=true;
EXPLAIN
SELECT substr(name, 1, 1) AS initial
FROM names
WHERE initial = 'D';
查询结果为:
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 11 0 0 Start at 11
1 OpenRead 0 7 0 2 0 root=7 iDb=0; names
2 Rewind 0 10 0 0
3 Column 0 1 2 0 r[2]=names.name
4 Function 6 2 1 substr(3) 0 r[1]=func(r[2..4])
5 Ne 5 9 1 80 if r[1]!=r[5] goto 9
6 Column 0 1 7 0 r[7]=names.name
7 Function 6 7 6 substr(3) 0 r[6]=func(r[7..9])
8 ResultRow 6 1 0 0 output=r[6]
9 Next 0 3 0 1
10 Halt 0 0 0 0
11 Transaction 0 0 10 0 1 usesStmtJournal=0
12 Integer 1 3 0 0 r[3]=1
13 Integer 1 4 0 0 r[4]=1
14 String8 0 5 0 D 0 r[5]='D'
15 Integer 1 8 0 0 r[8]=1
16 Integer 1 9 0 0 r[9]=1
17 Goto 0 1 0 0
在 addr
0 中,Init
操作码将我们发送到 addr
11,它打开新的 Transaction
.
紧接着 SQLite 分配整数 1 四次(addr
12-13、15-16)。这就是我开始怀疑 SQLite 可能人为地将 AS
之前的表达式复制到 WHERE
子句中的地方。
在操作码 3-5 中,发生在 SELECT
之前(操作码 6-8),我们可以看到 SQLite 将我们的 substr
复制到 WHERE
子句中。
DMBS 执行查询的顺序是:
FROM -> JOIN -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY -> LIMIT
我惊讶地发现这个查询在 SQLite 上运行良好:
SELECT *, duration / 60 AS length_in_hours
FROM movies
WHERE length_in_hours > 10;
为什么这个查询有效,而在某些 other cases 中它似乎失败了?
好的,所以我 运行 EXPLAIN
看看这里发生了什么。
.eqp full
PRAGMA vdbe_trace=true;
EXPLAIN
SELECT substr(name, 1, 1) AS initial
FROM names
WHERE initial = 'D';
查询结果为:
addr opcode p1 p2 p3 p4 p5 comment
---- ------------- ---- ---- ---- ------------- -- -------------
0 Init 0 11 0 0 Start at 11
1 OpenRead 0 7 0 2 0 root=7 iDb=0; names
2 Rewind 0 10 0 0
3 Column 0 1 2 0 r[2]=names.name
4 Function 6 2 1 substr(3) 0 r[1]=func(r[2..4])
5 Ne 5 9 1 80 if r[1]!=r[5] goto 9
6 Column 0 1 7 0 r[7]=names.name
7 Function 6 7 6 substr(3) 0 r[6]=func(r[7..9])
8 ResultRow 6 1 0 0 output=r[6]
9 Next 0 3 0 1
10 Halt 0 0 0 0
11 Transaction 0 0 10 0 1 usesStmtJournal=0
12 Integer 1 3 0 0 r[3]=1
13 Integer 1 4 0 0 r[4]=1
14 String8 0 5 0 D 0 r[5]='D'
15 Integer 1 8 0 0 r[8]=1
16 Integer 1 9 0 0 r[9]=1
17 Goto 0 1 0 0
在 addr
0 中,Init
操作码将我们发送到 addr
11,它打开新的 Transaction
.
紧接着 SQLite 分配整数 1 四次(addr
12-13、15-16)。这就是我开始怀疑 SQLite 可能人为地将 AS
之前的表达式复制到 WHERE
子句中的地方。
在操作码 3-5 中,发生在 SELECT
之前(操作码 6-8),我们可以看到 SQLite 将我们的 substr
复制到 WHERE
子句中。