我有一个包含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)')
答案 0 :(得分:0)
当您在表中搜索单个值时,查询优化器会估计结果要比搜索表中的所有值而不是单个值小得多。在后一种情况下,如果估计是正确的,那么通过索引查找行将比仅进行表扫描更慢。
在您的情况下,默认估计是错误的,因为大多数行实际上都是NULL。 要获取有关索引中值的分布的实际统计信息,请运行ANALYZE。
还考虑更新SQLite;较新版本应始终检测索引是覆盖索引。