我有一个软件,它接收一个数据库,并根据用户想要的内容(主要是SELECT AVG(<input1>) AS x, AVG(<intput2>) as y FROM <input3> WHERE <key> IN (<vals..> AND ...
形式的查询)使用它生成图形。这很好用。
我有一个简单的脚本,传递一个(通常很大)的文件,每个文件描述一行
name=foo
x=12
y=23.4
....... etc.......
脚本遍历每个文件,保存变量名称,并为每个文件添加INSERT
查询。然后它加载变量名称sort | uniq
,然后从中发出CREATE TABLE
语句(sqlite,有趣的是,将所有列都设为NUMERIC
即可,即使它们是实际上最终包含文本数据)。完成后,它会执行INSERTS
(在单个事务中,否则需要很长时间)。
为了提高性能,我在每一行添加了一个基本索引。但是,这会显着增加数据库大小,并且只能提供适度的改进。
数据有三种基本类型:
第一种类型显然不需要索引,因为它永远不会被分类。 第二种类型应该有一个索引,因为它通常会被过滤掉。 第三种类型可能不需要索引,因为它将用于输出。 在将特定值放入数据库之前确定特定值的类型会很烦人,但这是可能的。
我的问题有两个:
WHERE foo IN (5) AND bar IN (12,14,15)
形式的过滤查询?请注意,我不知道用户将选择哪些列,除了它将是类型2列。答案 0 :(得分:1)
阅读相关文档: Query Planning; Query Optimizer Overview; EXPLAIN QUERY PLAN
优化查询最重要的是避免I / O,因此不应对少于十行的表进行索引,因为无论如何所有数据都适合单个页面,因此使用索引只会强制SQLite读取另一个页面对于索引。
当您在大表中查找记录时,索引非常重要。
无关索引使表更新速度变慢,因为每个索引也需要更新。
SQLite在查询中每个表最多只能使用一个索引。
通过在两列foo
和bar
上设置单个索引,可以最佳地优化此特定查询。
但是,为查找列的所有可能组合创建此类索引很可能不值得。
如果查询是动态生成的,那么最好的想法可能是为每个具有良好选择性的列创建一个索引,并依靠SQLite来选择最好的一个。
不要忘记运行ANALYZE。