我有两张表:
table1 (about 200000 records)
number varchar(8)
table2 (about 2000000 records)
number varchar(8)两个表中的字段“number”都有标准索引。对于table1中的每条记录,在table2中分配了大约10条记录。
我执行查询:
explain select table1.number from table1, table2 where table1.number = table2.number;查询计划显示索引将不会被使用,Seq遍历;)
但是,如果我将table1中的记录量减少到2000左右,查询计划就会开始显示将使用该索引。
也许有人能告诉我为什么postgresql会这样呢?
发布于 2009-12-04 01:41:23
对于选择性非常低的查询,顺序扫描是正常的(也是最佳的)--也就是说,对于遍历整个表的查询。
当您从table1中删除大多数行时,它不再覆盖table2中所有可能的不同值--这就是为什么要使用索引扫描。
对于初学者,我建议尝试这个查询:
select * from pg_stats where tablename in ('table1','table2'); 这是PostgreSQL用来构建查询计划的信息。
计划器本身是相当复杂的-如果你很好奇,请参考文档(Jonathan提到的)和资源[http://doxygen.postgresql.org/ ->源/后端/优化器]。
发布于 2009-12-03 22:29:56
是的,PostgreSQL docs可以告诉你!
以下是一些亮点:
当不使用索引时,它对于强制使用索引的测试很有用。有一些运行时参数可以关闭各种计划类型(参见第18.6.1节)。例如,关闭顺序扫描(enable_seqscan)和嵌套循环联接(enable_nestloop)是最基本的计划,这将迫使系统使用不同的计划。如果系统仍然选择顺序扫描或嵌套循环联接,则可能存在不使用索引的更根本原因;例如,查询条件与索引不匹配。(什么类型的查询可以使用什么类型的索引在前面的小节中进行了解释。)
如果强制使用索引确实使用了索引,那么有两种可能性:要么系统是正确的,使用索引确实不合适,要么查询计划的成本估计没有反映现实。因此,您应该对使用和不使用索引的查询进行计时。EXPLAIN ANALYZE命令在这里很有用。
发布于 2009-12-03 22:28:30
这可能取决于创建索引的方式。如果" number“实际上是一个数字,那么您应该考虑将列类型更改为bigint。同样,不是100%确定,但我认为在字符列上的索引与在基于数字的字段上的工作方式不同……然而,我可能是在胡说。
https://stackoverflow.com/questions/1840159
复制相似问题