【发布时间】:2014-09-20 01:19:09
【问题描述】:
我正在开发一个使用 PostgreSQL9.3 的项目。我使用下面的查询来展示选择性估计错误如何导致使用 PostgreSQL8.3 在 TPC-H 工作负载上的查询执行时间增加数倍。
select
n_name,
sum(l_extendedprice * (1 - l_discount)) as revenue
from
customer,
orders,
lineitem,
supplier,
nation,
region
where
c_custkey = o_custkey
and l_orderkey = o_orderkey
and l_suppkey = s_suppkey
and c_nationkey = s_nationkey
and s_nationkey = n_nationkey
and n_regionkey = r_regionkey
and (r_name='ASIA' or r_name='AFRICA')
and o_orderdate >= date '1994-01-01'
and o_orderdate < date '1994-01-01' + interval '1 year'
and l_shipdate <= l_receiptdate
and l_commitdate <= l_shipdate + integer '90'
and l_extendedprice <= 20000
and c_name like '%r#00%'
and c_acctbal <=2400
group by
n_name
order by
revenue desc
问题在于 PostgreSQL8.3 选择了一个涉及大量 NestedLoop 连接的计划,因为对 lineitem 和客户的选择性估计错误很大。我认为这主要是由于 LIKE 模式匹配。但最佳方案应该是使用 Hash Joins。
最近我为我的项目升级到 PostgreSQL9.3 并观察到上述查询不再给出错误的计划。我花了一些时间试图在 TPC-H 1GB 数据上找到具有较大 基数估计错误 的查询,但到目前为止还没有成功。是否有任何 PostgreSQL 极客知道 TPC-H 基准测试中的一些现成查询或任何显示 PostgreSQL9.3 中基数估计错误的查询
【问题讨论】:
-
很遗憾,您的问题的答案是否定的,尽管我遇到过它们。您正在使用 pre ansi-92 标准进行连接...我记得在 8.x 的日子里,我偶尔会得到非常糟糕的执行计划,而重写为 ansi-92 语法改进了它......我认为 9.3 改进了它能够处理这种语法
-
问题可能适合 dba.SE。
-
@Twelfth:对于 Postgres 查询计划器,
WHERE子句和INNER JOIN子句在内部都是相同的,AFAIK。显式连接语法仍然更易于阅读和维护。 -
@ErwinBrandstetter - 我也是这么想的,但是我之前在 where 子句连接上提出了一些非常糟糕的执行计划……不过那是几年前的事了。
-
@Twelfth:我提供了一个答案来解决这个问题。
标签: sql postgresql