我有兴趣了解有关postgres优化器的更多信息 .
例如,如果您有查询
select * from table where field = value limit 1;
但是所有字段值都为空 . 随着表的增长或者优化阶段的确定(以某种方式不涉及传递整个表),没有符合要求的值,字段索引是否仍会使查询更快?
我问,因为我们有一个情况,我们有一个未经优化的简单查询(上面的表格和列未被索引的地方)被忽视,即使表有数百万条记录,直到有一天注入一些实际值,突然一切死了 .
如果 field 的所有值都为null,则上述查询将始终不返回任何行,因为 field = value 隐含 field is not null . 空值只能由 is null 或 is not null 运算符进行测试 .
field
field = value
field is not null
is null
is not null
无论如何,索引(除了HASH和GIN之外的所有类型)都存储空值,因此可以改进像 filed is null 或 field is not null 这样的查询 . 但这实际上取决于您的确切查询和值的分布 .
filed is null
索引通常仅在它们是选择性时才有用,即当只有相对较小比例的行与索引匹配时 . 因此,通常一个列上的索引都是一个值(null或其他)将不会被使用,因为顺序扫描会更快 .
另一个索引可能有用的是,当通过仅索引扫描完全从索引中获得部分查询时 . 您可能无法使用全部为空的列来执行此操作,但如果将列启用仅限索引扫描用于频繁使用的查询,则可以选择将该列合并到复合索引中 .
2 回答
如果
field
的所有值都为null,则上述查询将始终不返回任何行,因为field = value
隐含field is not null
. 空值只能由is null
或is not null
运算符进行测试 .无论如何,索引(除了HASH和GIN之外的所有类型)都存储空值,因此可以改进像
filed is null
或field is not null
这样的查询 . 但这实际上取决于您的确切查询和值的分布 .索引通常仅在它们是选择性时才有用,即当只有相对较小比例的行与索引匹配时 . 因此,通常一个列上的索引都是一个值(null或其他)将不会被使用,因为顺序扫描会更快 .
另一个索引可能有用的是,当通过仅索引扫描完全从索引中获得部分查询时 . 您可能无法使用全部为空的列来执行此操作,但如果将列启用仅限索引扫描用于频繁使用的查询,则可以选择将该列合并到复合索引中 .