何时包含索引(自动启发式)

时间:2013-08-06 20:34:32

标签: sqlite indexing

我有一个软件,它接收一个数据库,并根据用户想要的内容(主要是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. 一些值(&lt; 10),表示使用的输入参数
  3. 许多值(> 1000),主要是输出数据。
  4. 第一种类型显然不需要索引,因为它永远不会被分类。 第二种类型应该有一个索引,因为它通常会被过滤掉。 第三种类型可能不需要索引,因为它将用于输出。 在将特定值放入数据库之前确定特定值的类型会很烦人,但这是可能的。

    我的问题有两个:

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

1 个答案:

答案 0 :(得分:1)

阅读相关文档: Query Planning; Query Optimizer Overview; EXPLAIN QUERY PLAN

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

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

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

  2. SQLite在查询中每个表最多只能使用一个索引。 通过在两列foobar上设置单个索引,可以最佳地优化此特定查询。 但是,为查找列的所有可能组合创建此类索引很可能不值得。 如果查询是动态生成的,那么最好的想法可能是为每个具有良好选择性的列创建一个索引,并依靠SQLite来选择最好的一个。

  3. 不要忘记运行ANALYZE