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

时间:2009-12-03 14:23:27

标签: sql postgresql

我有两张桌子:

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遍布;)

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

也许有人可以告诉我为什么postgresql以这种方式行事?

3 个答案:

答案 0 :(得分:4)

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

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

对于初学者,我建议您尝试此查询:

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

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

规划师本身非常复杂 - 请参阅文档(由Jonathan提及)和来源[http://doxygen.postgresql.org/ - > src / backend / optimizer]如果你好奇的话。

答案 1 :(得分:2)

是的,PostgreSQL docs可以告诉你!

以下是一些亮点:

  

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

     

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

答案 2 :(得分:-1)

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