3

我在 SQLite 数据库中有一个简单的表(大约 8 列和很多行)。有一个程序作为服务运行并经常(大约每 5 分钟)对表执行选择、更新和插入操作。选择仅用于确定要更新哪些行,它们基于保存布尔值的列(可能由 SQLite 在内部转换为整数)。

还有一个 Web 应用程序在 Web 用户希望查看部分数据时执行选择(始终使用 GROUP BY 子句)。

有两种方法可以通过 Web 应用程序请求数据:(a) 预定义过滤器(即 where 子句在 3 个特定列上具有特定条件)和 (b) 自定义过滤器(即用户选择条件的值,但参与 where 子句的列与 (a)) 中的相同。如前所述,在这两种情况下都有一个 GROUP BY 操作。

我想知道使用视图或自定义函数是否会提高性能。目前,“自定义”选择可能需要 30 多秒才能完成 - 这是在将任何数据发送回用户之前。

编辑:在“预定义”选择语句上使用 EXPLAIN QUERY PLAN 只会产生一行:

0|0|TABLE mytable

在同一个查询上使用 EXPLAIN 会产生以下结果:

0|OpenVirtual|1|4|keyinfo(2,-BINARY,BINARY)
1|OpenVirtual|2|3|keyinfo(1,BINARY)
2|MemInt|0|5|
3|MemInt|0|4|
4|Goto|0|27|
5|MemInt|1|5|
6|Return|0|0|
7|IfMemPos|4|9|
8|Return|0|0|
9|AggFinal|0|0|count(0)
10|AggFinal|2|1|sum(1)
11|MemLoad|0|0|
12|MemLoad|1|0|
13|MemLoad|2|0|
14|MakeRecord|3|0|
15|MemLoad|0|0|
16|MemLoad|1|0|
17|Sequence|1|0|
18|Pull|3|0|
19|MakeRecord|4|0|
20|IdxInsert|1|0|
21|Return|0|0|
22|MemNull|1|0|
23|MemNull|3|0|
24|MemNull|0|0|
25|MemNull|2|0|
26|Return|0|0|
27|Gosub|0|22|
28|Goto|0|82|
29|Integer|0|0|
30|OpenRead|0|2|
31|SetNumColumns|0|9|
32|Rewind|0|48|
33|Column|0|8|
34|String8|0|0|123456789
35|Le|356|39|collseq(BINARY)
36|Column|0|3|
37|Integer|180|0|
38|Gt|100|42|collseq(BINARY)
39|Column|0|7|
40|Integer|1|0|
41|Ne|356|47|collseq(BINARY)
42|Column|0|6|
43|Sequence|2|0|
44|Column|0|3|
45|MakeRecord|3|0|
46|IdxInsert|2|0|
47|Next|0|33|
48|Close|0|0|
49|Sort|2|69|
50|Column|2|0|
51|MemStore|7|0|
52|MemLoad|6|0|
53|Eq|512|58|collseq(BINARY)
54|MemMove|6|7|
55|Gosub|0|7|
56|IfMemPos|5|69|
57|Gosub|0|22|
58|AggStep|0|0|count(0)
59|Column|2|2|
60|Integer|30|0|
61|Add|0|0|
62|ToReal|0|0|
63|AggStep|2|1|sum(1)
64|Column|2|0|
65|MemStore|1|1|
66|MemInt|1|4|
67|Next|2|50|
68|Gosub|0|7|
69|OpenPseudo|3|0|
70|SetNumColumns|3|3|
71|Sort|1|80|
72|Integer|1|0|
73|Column|1|3|
74|Insert|3|0|
75|Column|3|0|
76|Column|3|1|
77|Column|3|2|
78|Callback|3|0|
79|Next|1|72|
80|Close|3|0|
81|Halt|0|0|
82|Transaction|0|0|
83|VerifyCookie|0|1|
84|Goto|0|29|
85|Noop|0|0|

我使用的选择如下

SELECT 
    COUNT(*) as number, 
    field1, 
    SUM(CAST(filter2 +30 AS float)) as column2 
FROM 
    mytable 
WHERE 
    (filter1 > '123456789'  AND filter2 > 180) 
    OR filter3=1 
GROUP BY 
    field1 
ORDER BY 
    number DESC, field1;
4

1 回答 1

1

每当您要对非主键字段进行比较时,将索引添加到字段中是一个很好的设计理念。但是,太多可能会导致INSERTs 爬行,因此请相应地进行计划。

此外,如果您有简单的字段,例如仅包含布尔值的字段,您可能需要考虑将其声明为 anINTEGER而不是您声明的任何内容。将其声明为 SQLite 未明确定义的任何类型将导致其默认为比较值需要更长时间的NUMERIC类型,因为它将在内部将其存储为 adouble并将使用浮点数学处理器而不是整数数学处理器。

IMO,GROUP BY排序指令有时对未优化的查询是一个致命的赠品;它的方法包括消除冗余数据,如果一开始就没有将其从数据库中提取出来,这些冗余数据可能会被预先消除。

编辑:

我看到了您的查询,并看到您可以做一些简单的事情来优化它:

  • SUM(CAST(filter2 +30 AS float))效率低下;你为什么要把它当作一个浮点数?为什么不只是SUM它然后添加 30 * COUNT

  • filter1 > '123456789'- 为什么是字符串比较?为什么不只使用整数比较?

于 2012-05-07T15:34:53.460 回答