2009-12-03 31 views
1

我有两个表:PostgreSQL 8.3版本,简单的查询不使用索引

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; 

查询计划显示索引不会,序列扫描各地使用;)

但是,如果我减少表1至〜2000查询计划的记录量开始显示索引将被使用。

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

回答

-1

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

+1

由于过去的设计决定,它并不总是一个数字 – 2009-12-03 14:34:15

2

是的,PostgreSQL docs可以告诉你!

这里有一些亮点:

进行测试,以迫使其使用

当不使用索引,也可以是 有用。 有运行时参数,可以 关闭各种计划类型(请参阅 第18.6.1节)。例如,关闭 基本计划的顺序扫描(enable_seqscan) 和嵌套循环联接 (enable_nestloop)将会强制系统 使用不同的计划。如果系统 仍然选择顺序扫描或 嵌套循环联接,则存在 可能是为什么 索引未被使用的更根本原因;例如,对于 示例,查询条件不匹配 索引。 (什么样的查询 可以用什么样的指标是 在前面的章节中说明)。

如果强制使用索引不会使用 指数,那么有两种 可能性:要么该系统是 权和使用该索引的确不是 不合适,或者查询计划的成本估计 并不反映 的现实。所以你应该用你的查询 加上和不加索引。 EXPLAIN ANALYZE命令在这里可能很有用。

4

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

从table1中删除大多数行时,它不再覆盖table2中所有可能的不同值 - 这就是为什么要使用索引扫描。

对于初学者来说,我建议你尝试此查询:

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

这是PostgreSQL使用建立查询计划的信息。

计划者本身相当复杂 - 如果你很好奇,请参考文档(由Jonathan提及)和来源[http://doxygen.postgresql.org/ - > src/backend/optimizer]。

+0

+1这是关于值的基数。 – Trey 2009-12-03 19:29:46