SQLite bug 或错误的查询

问题描述 投票:0回答:1

我在 SQLite 中创建了一个大约 3M 行的数据库,我也用它来测试函数或小实验。我的最后一个实验是检查随机函数的分布,所以我写了这个查询:

SELECT b.a , count(*)
FROM(
    SELECT abs(random()) % 10 a
    FROM fdic) b 
GROUP BY b.a 
ORDER BY b.a

它适用于每个 SQLite 数据库,只需将表 fdic 替换为您的表即可。 我得到以下回复:

a 计数(*)
1 318161
9 316810
5 317591
9 316006
2 317502
6 317131
6 316093
6 318442
2 317923
6 316793

当然,由于 random() 函数,你不会得到两次相同的答案。但如果你分析答案有两个问题,第一个是不“分组”,例如有4倍的值6,两倍的值2等等。 第二个问题是不排序,值未排序。 所以在报告错误之前,我想问你:

您注意到我的查询中有错误吗?

(带有fdic表的数据库已上线,不知道Stackoverflow是否允许发布地址,如果需要数据库请在评论中询问)

sqlite
1个回答
0
投票
sqlite> EXPLAIN SELECT b.a , count(*) FROM(SELECT abs(random()) % 10 a FROM fdic) b GROUP BY b.a ORDER BY b.a;
addr  opcode         p1    p2    p3    p4             p5  comment      
----  -------------  ----  ----  ----  -------------  --  -------------
0     Init           0     46    0                    0   Start at 46
1     Noop           2     4     0                    0   
2     SorterOpen     3     1     0     k(1,B)         0   
3     Integer        0     2     0                    0   r[2]=0; clear abort flag
4     Null           0     5     5                    0   r[5..5]=NULL
5     Gosub          4     42    0                    0   
6     OpenRead       1     2     0     0              0   root=2 iDb=0; fdic
7     Rewind         1     15    0                    0   
8       Function       0     0     10    random(0)      0   r[10]=func()
9       Function       0     10    9     abs(1)         0   r[9]=func(r[10])
10      Remainder      11    9     8                    0   r[8]=r[9]%r[11]
11      ClrSubtype     8     0     0                    0   r[8].subtype = 0
12      MakeRecord     8     1     9                    0   r[9]=mkrec(r[8])
13      SorterInsert   3     9     0                    0   key=r[9]
14    Next           1     8     0                    1   
15    OpenPseudo     4     8     1                    0   1 columns in r[8]
16    SorterSort     3     45    0                    0   GROUP BY sort
17      SorterData     3     8     4                    0   r[8]=data
18      Column         4     0     6                    0   r[6]= cursor 4 column 0
19      Compare        5     6     1     k(1,B)         0   r[5] <-> r[6]
20      Jump           21    25    21                   0   
21      Move           6     5     1                    0   r[5]=r[6]
22      Gosub          3     32    0                    0   output one row
23      IfPos          2     45    0                    0   if r[2]>0 then r[2]-=0, goto 45; check abort flag
24      Gosub          4     42    0                    0   reset accumulator
25      AggStep        0     0     7     count(0)       0   accum=r[7] step(r[0])
26      Integer        1     1     0                    0   r[1]=1; indicate data in accumulator
27    SorterNext     3     17    0                    0   
28    Gosub          3     32    0                    0   output final row
29    Goto           0     45    0                    0   
30    Integer        1     2     0                    0   r[2]=1; set abort flag
31    Return         3     0     0                    0   
32    IfPos          1     34    0                    0   if r[1]>0 then r[1]-=0, goto 34; Groupby result generator entry point
33    Return         3     0     0                    0   
34    AggFinal       7     0     0     count(0)       0   accum=r[7] N=0
35    Function       0     0     10    random(0)      0   r[10]=func()
36    Function       0     10    9     abs(1)         0   r[9]=func(r[10])
37    Remainder      11    9     12                   0   r[12]=r[9]%r[11]
38    ClrSubtype     12    0     0                    0   r[12].subtype = 0
39    Copy           7     13    0                    0   r[13]=r[7]
40    ResultRow      12    2     0                    0   output=r[12..13]
41    Return         3     0     0                    0   end groupby result generator
42    Null           0     7     7                    0   r[7..7]=NULL
43    Integer        0     1     0                    0   r[1]=0; indicate accumulator empty
44    Return         4     0     0                    0   
45    Halt           0     0     0                    0   
46    Transaction    0     0     2     1              1   usesStmtJournal=0
47    Integer        10    11    0                    0   r[11]=10
48    Goto           0     1     0                    0   

参见第8行和第35行:子查询执行了两次。这种情况可能发生在许多数据库引擎中,而不仅仅是 SQLite。通常,这应该不重要,因为重复查询不会改变结果。

© www.soinside.com 2019 - 2024. All rights reserved.