【发布时间】:2018-08-01 00:54:51
【问题描述】:
我有一个类似的 SQL 查询:
select *
from customers
where customer_id > 0
order by customer_id asc
limit 500;
而customer_id 是customers 表的主键。当我执行此查询并检查执行计划时。我看到它扫描整个表:
SELECT (select) 500 23.0 0.0 Node Type = Limit;
Parallel Aware = false;
Startup Cost = 0.43;
Total Cost = 23.16;
Plan Rows = 500;
Plan Width = 237;
TRANSFORM (Limit) 500 23.0 0.0 Node Type = Limit;
Parallel Aware = false;
Startup Cost = 0.43;
Total Cost = 23.16;
Plan Rows = 500;
Plan Width = 237;
INDEX_SCAN (Index Scan) table: customers; index: pk12; 3262339 148316.0 0.0 Node Type = Index Scan;
Parent Relationship = Outer;
Parallel Aware = false;
Scan Direction = Forward;
Index Name = pk12;
Relation Name = customers;
Alias = customers;
Startup Cost = 0.43;
Total Cost = 148316.36;
Plan Rows = 3222222;
Plan Width = 237;
Index Cond = (customer_id > '0'::numeric);
在我的直觉中,主键会创建索引,sql 引擎可以定位下限并从索引的叶节点(b+ 树)中获取 500 个项目。这是我能想到的最快的执行计划。为什么sql引擎会扫描整个DB表,先排序,只得到500条?
PS:PostgreSQL。
【问题讨论】:
-
注意到索引扫描中的
'0'::numeric,id 列是数字类型吗?这也可能是一个统计问题。是否禁用了 autovacuum?尝试ANALYZE <table_name>;收集有关该特定表的统计信息。
标签: sql postgresql primary-key sql-execution-plan