Postgresql 8.3,不使用索引的简单查询

Posted

技术标签:

【中文标题】Postgresql 8.3,不使用索引的简单查询【英文标题】:Postgresql 8.3, simple query not using index 【发布时间】:2009-12-03 14:23:27 【问题描述】:

我有两张桌子:

table1 (about 200000 records)
 number varchar(8) 

table2 (about 2000000 records)
 number varchar(8)

两个表中的“数字”字段都有标准索引。 对于 table1 中的每条记录,table2 中分配了大约 10 条记录。

我执行查询:

explain select table1.number from table1, table2 where table1.number = table2.number;

查询计划显示不会使用索引,Seq Scans all over ;)

但如果我将 table1 中的记录数量减少到 ~2000 条查询计划开始显示该索引将被使用。

也许有人可以告诉我为什么 postgresql 会这样?

【问题讨论】:

【参考方案1】:

对于选择性非常低的查询,即遍历整个表的查询,顺序扫描是正常的(也是最佳的)。

当您从 table1 中删除大多数行时,它不再涵盖 table2 中所有可能的不同值 - 这就是使用索引扫描的原因。

对于初学者,我建议尝试以下查询:

select * from pg_stats where tablename in ('table1','table2'); 

这是 PostgreSQL 用来构建查询计划的信息。

规划器本身相当复杂 - 如果您很好奇,请查阅文档(Jonathan 提到)和来源 [http://doxygen.postgresql.org/ -> src/backend/optimizer]。

【讨论】:

【参考方案2】:

是的,PostgreSQL docs 可以告诉你!

这里有一些亮点:

不使用索引时,可以 用于测试以强制使用它们。 有运行时参数可以 关闭各种计划类型(请参阅 第 18.6.1 节)。例如,转 关闭顺序扫描 (enable_seqscan) 和嵌套循环连接 (enable_nestloop),这是最 基本计划,将迫使系统 使用不同的计划。如果系统 仍然选择顺序扫描或 嵌套循环连接然后有 可能是一个更根本的原因 该索引未被使用;为了 例如,查询条件不 匹配索引。 (什么样的查询 可以使用什么样的索引 在前面的部分中进行了解释。)

如果强制索引使用确实使用 索引,那么有两个 可能性:要么系统是 正确,使用索引确实是 不合适,或成本估算 的查询计划没有反映 现实。所以你应该计时你的查询 有和没有索引。解释 ANALYZE 命令在这里很有用。

【讨论】:

【参考方案3】:

这可能取决于创建索引的方式。如果“数字”实际上是一个数字,您应该考虑将列类型更改为 bigint。同样,不是 100% 确定,但我认为字符列上的索引与基于数字的字段的工作方式不同......但是我可能会说出来。

【讨论】:

由于过去的设计决策,它并不总是一个数字

以上是关于Postgresql 8.3,不使用索引的简单查询的主要内容,如果未能解决你的问题,请参考以下文章

如何在 PostgreSQL 8.3 中执行窗口函数

PostgreSQL:未使用的索引导致查询性能不佳?

为啥此查询在 PostgreSQL 中不使用仅索引扫描?

我如何知道查询中是不是使用了任何索引 | PostgreSQL 11?

PostgreSQL 未对过滤的多重排序查询使用索引

为啥 PostgreSQL 不使用三元索引