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,不使用索引的简单查询的主要内容,如果未能解决你的问题,请参考以下文章