Postgres 中的索引扫描与顺序扫描

时间:2021-03-26 16:22:09

标签: sql database postgresql indexing query-optimization

我正在使用 Postgres 数据库,我试图在 1000000 行的表上查看索引扫描和顺序扫描之间的区别

描述表格

\d grades 

enter image description here

然后解释分析 10 到 500000 之间的行

explain analyze select name from grades where pid between 10 and 500000 ; 

enter image description here

然后解释分析 10 到 600000 之间的行

explain analyze select name from grades where pid between 10 and 600000 ;

enter image description here

<块引用>

我很奇怪为什么它在第一次查询时进行索引扫描并且 尽管它们按同一列查询,但在第二个顺序扫描 它包含在索引中。

3 个答案:

答案 0 :(得分:3)

如果你只需要一个表行,索引扫描比顺序扫描快得多。如果需要整个表,顺序扫描比索引扫描快。
介于两者之间的是 PostgreSQL 在这两种访问方式之间切换的转折点。

您可以调整 random_page_cost 以影响选择顺序扫描的点。如果您有 SSD 存储,您应该将该参数设置为 1.0 或 1.1,以告诉 PostgreSQL 索引扫描在您的硬件上更便宜。

答案 1 :(得分:1)

PostgreSQL 使用基于成本的优化器,而不是基于规则的优化器。如果您采用索引扫描的估计成本 18693,并通过两个计划之间预期行的比率线性扩大它(这不完全是计划者所做的,但应该是一个足够好的初步近似值),你会得到22330。这比seq扫描的预期成本高,21372,所以它选择seq扫描。

如果你以同样的方式扩大索引扫描的实际时间,你会得到 89 毫秒,这比实际的 seq 扫描略快。所以也许规划者在这里犯了一个很小的错误,但在实践中肯定没有什么可担心的。

如果运行时间的差异是 10 倍,而不是 10%,那可能值得进一步研究。

答案 2 :(得分:0)

这是因为如果 SELECT 返回超过表中所有行的大约 5-10%,顺序扫描比索引扫描快得多。并且您的第二个查询达到了该阈值;因为您正在获取更多行