PostgreSQL解释计划中的成本计量的可靠性如何?

PostgreSQL解释计划中的成本计量的可靠性如何?,sql,postgresql,database-performance,explain,sql-execution-plan,Sql,Postgresql,Database Performance,Explain,Sql Execution Plan,查询是在一个有1100万行的大表上执行的。在执行查询之前,我已经对表执行了ANALYZE 查询1: SELECT * FROM accounts t1 LEFT OUTER JOIN accounts t2 ON (t1.account_no = t2.account_no AND t1.effective_date < t2.effective_date) WHERE t2.account_no IS NULL; SELECT t1.* FROM accoun

查询是在一个有1100万行的大表上执行的。在执行查询之前,我已经对表执行了
ANALYZE

查询1:

SELECT *
FROM accounts t1
LEFT OUTER JOIN accounts t2 
    ON (t1.account_no = t2.account_no
        AND t1.effective_date < t2.effective_date)
WHERE t2.account_no IS NULL;
SELECT t1.*
FROM accounts t1
LEFT OUTER JOIN accounts t2 
    ON (t1.account_no = t2.account_no
        AND t1.effective_date < t2.effective_date)
WHERE t2.account_no IS NULL;
SELECT *
FROM accounts
WHERE (account_no,
       effective_date) IN
    (SELECT account_no,
            max(effective_date)
     FROM accounts
     GROUP BY account_no);
Nested Loop  (cost=406416.19..502216.84 rows=2763695 width=146) (actual time=31779.457..917543.228 rows=1977871 loops=1)
  ->  HashAggregate  (cost=406416.19..406757.45 rows=34126 width=43) (actual time=31774.877..33378.968 rows=1977425 loops=1)
        ->  Subquery Scan on "ANY_subquery"  (cost=397884.72..404709.90 rows=341259 width=43) (actual time=27979.226..29841.217 rows=1977425 loops=1)
              ->  HashAggregate  (cost=397884.72..401297.31 rows=341259 width=18) (actual time=27979.224..29315.346 rows=1977425 loops=1)
                    ->  Seq Scan on accounts  (cost=0.00..342610.81 rows=11054781 width=18) (actual time=0.851..16092.755 rows=11034070 loops=1)
  ->  Index Scan using accounts_idx2 on accounts  (cost=0.00..2.78 rows=1 width=146) (actual time=0.443..0.445 rows=1 loops=1977425)
        Index Cond: (((account_no)::text = ("ANY_subquery".account_no)::text) AND ((effective_date)::text = "ANY_subquery".max))
Total runtime: 918039.614 ms
解释分析:

SELECT *
FROM accounts t1
LEFT OUTER JOIN accounts t2 
    ON (t1.account_no = t2.account_no
        AND t1.effective_date < t2.effective_date)
WHERE t2.account_no IS NULL;
SELECT t1.*
FROM accounts t1
LEFT OUTER JOIN accounts t2 
    ON (t1.account_no = t2.account_no
        AND t1.effective_date < t2.effective_date)
WHERE t2.account_no IS NULL;
SELECT *
FROM accounts
WHERE (account_no,
       effective_date) IN
    (SELECT account_no,
            max(effective_date)
     FROM accounts
     GROUP BY account_no);
Nested Loop  (cost=406416.19..502216.84 rows=2763695 width=146) (actual time=31779.457..917543.228 rows=1977871 loops=1)
  ->  HashAggregate  (cost=406416.19..406757.45 rows=34126 width=43) (actual time=31774.877..33378.968 rows=1977425 loops=1)
        ->  Subquery Scan on "ANY_subquery"  (cost=397884.72..404709.90 rows=341259 width=43) (actual time=27979.226..29841.217 rows=1977425 loops=1)
              ->  HashAggregate  (cost=397884.72..401297.31 rows=341259 width=18) (actual time=27979.224..29315.346 rows=1977425 loops=1)
                    ->  Seq Scan on accounts  (cost=0.00..342610.81 rows=11054781 width=18) (actual time=0.851..16092.755 rows=11034070 loops=1)
  ->  Index Scan using accounts_idx2 on accounts  (cost=0.00..2.78 rows=1 width=146) (actual time=0.443..0.445 rows=1 loops=1977425)
        Index Cond: (((account_no)::text = ("ANY_subquery".account_no)::text) AND ((effective_date)::text = "ANY_subquery".max))
Total runtime: 918039.614 ms
估计成本约为502000,但实际花费的时间约为15.3分钟

  • EXPLAIN
    输出的可靠性如何
  • 我们是否总是必须
    解释分析
    以查看我们的查询将如何在真实数据上执行,并且不信任查询规划人员认为它将花费多少

它们是可靠的,除非它们不可靠。你不能真的一概而论


它似乎大大低估了它将发现的不同帐户的数量(认为它将发现34126个实际发现1977425个)。您的默认\u statistics\u目标可能不够高,无法获得此列的良好估计值。

成本是一个任意数字。成本只是相对的,它们没有单位,也没有外部意义。您可以通过比较一组查询的成本估计和执行时间来估计机器从查询成本到执行时间的粗略转换系数,但这是唯一的方法。成本估算的可靠性在很大程度上取决于计划员的工作有多出色,表统计信息的最新程度和详细程度,以及是否遇到任何已知的成本估算问题,如相关列。“通过比较一组查询的成本估算和执行时间,您可以估算机器从查询成本到执行时间的粗略转换系数“在上述情况下,粗略的换算系数是完全无用的。如果我粗略估计查询1和查询2的成本-时间转换系数,我认为查询3不应该花费超过45秒的时间。但这需要15分钟以上?为什么?换句话说,成本似乎具有高度误导性。如果我相信成本,我会选择查询3而不是查询2,但实际执行时间表明,我真的应该选择查询2而不是查询3。Planner肯定错估了这一点。很难说为什么没有更多的挖掘。行数估计是合理的(请参阅)。看起来索引扫描的时间比Pg预期的要长<代码>随机页面成本太低,无法反映现实?像这样的事情恐怕需要一些挖掘,所以成本并不是对查询执行时间的一个很好的估计。不仅仅是因为在10倍左右的范围内通常被认为是相当不错的。它们是计划者的成本参数,用于比较替代计划,仅此而已。这是一个很好的提示!我想当估计值不好时,其中一个线索就是估计的行数与实际行数不够接近。“它们是可靠的,除非它们不是。你不能真正概括。”这句话非常有用!我想知道,这个答案是怎么被接受的。