1

我有一个软件,它接收一个数据库,并使用它根据用户想要的内容生成图形(主要是表单的查询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(在单个事务中,否则将花费很长时间)。

为了提高性能,我在每一行添加了一个基本索引。但是,这会显着增加数据库大小,并且仅提供适度的改进。

数据分为三种基本类型:

  1. 单个值,表示程序版本等。
  2. 一些值(<10),表示使用的输入参数等内容
  3. 许多值(> 1000),主要是输出数据。

第一种类型显然不需要索引,因为它永远不会被排序。第二种类型应该有一个索引,因为它通常会被过滤。第三种类型可能不需要索引,因为它将用于输出。在将特定值放入数据库之前确定它是哪种类型会很烦人,但这是可能的。

我的问题是双重的:

  1. 除了我所看到的大小增加之外,是否有一些无关索引的隐藏成本?
  2. 有没有更好的方法来索引表单的过滤查询WHERE foo IN (5) AND bar IN (12,14,15)?请注意,我不知道用户将选择哪些列,除了它将是类型 2 列。
4

1 回答 1

1

阅读相关文档: 查询计划查询优化器概述解释查询计划

优化查询最重要的是避免 I/O,因此不应该对少于 10 行的表进行索引,因为无论如何所有数据都适合单个页面,因此拥有索引只会迫使 SQLite 为索引读取另一个页面.

当您在大表中查找记录时,索引很重要。

  1. 无关索引使表更新变慢,因为每个索引也需要更新。

  2. SQLite 在查询中每个表最多可以使用一个索引。通过在两列foobar. 但是,为查找列的所有可能组合创建此类索引很可能不值得付出努力。如果查询是动态生成的,最好的办法可能是为具有良好选择性的每一列创建一个索引,并依靠 SQLite 来选择最好的一个。

不要忘记运行ANALYZE

于 2013-08-07T07:24:00.090 回答