SQLITE3 - 为什么计数' null'记录速度超过计数速度的100倍' not null'索引列中的记录?

时间:2015-04-13 02:09:00

标签: sqlite

我有一个包含300,000行的表,索引列是一个大文本块或NULL。目前大约250,000行是NULL,其他50,000行填充文本。

c.execute('SELECT count(*) FROM table WHERE indexed_column IS NULL)

这会在一秒钟内计算行数。

c.execute('SELECT count(*) FROM table WHERE indexed_column IS NOT NULL)

c.execute('SELECT count(*) FROM table)

这两个陈述都需要大约180秒才能完成计算。

为什么在识别NULL值和NOT NULL时存在如此巨大的速度差异?有没有更快的方法来计算NOT NULL值?

IS NULL的查询计划:

(0, 0, 0, 'SEARCH TABLE table_name USING INDEX column_index (column=?) (~10 rows)')

IS NOT NULL的查询计划:

(0, 0, 0, 'SCAN TABLE table_name (~500000 rows)')

1 个答案:

答案 0 :(得分:0)

当您在表中搜索单个值时,查询优化器会估计结果要比搜索表中的所有值而不是单个值小得多。在后一种情况下,如果估计是正确的,那么通过索引查找行将比仅进行表扫描更慢。

在您的情况下,默认估计是错误的,因为大多数行实际上都是NULL。 要获取有关索引中值的分布的实际统计信息,请运行ANALYZE

还考虑更新SQLite;较新版本应始终检测索引是覆盖索引。