【问题标题】:PostgreSQL : query plan delay at startPostgreSQL:开始时的查询计划延迟
【发布时间】:2014-04-17 15:48:32
【问题描述】:

我们在一张大表上使用单列索引来尝试快速 列上的“选择不同的”。

这曾经可以正常工作,但是……现在不行了。我们不知道什么 发生了。

以下是事实:

  • 请求:

    SELECT  dwhinv___rfovsnide::varchar 
    FROM dwhinv 
    WHERE dwhinv___rfovsnide >  '201212_cloture' 
    ORDER BY dwhinv___rfovsnide LIMIT 1
    

为了“模拟”不同,我们多次播放此查询,每次更改 dwhinv___rfovsnide 值以获得下一个值。

正常查询时间在1ms以下。

  • 计划:

    Limit  (cost=0.00..1.13 rows=1 width=12) (actual time=5798.915..5798.916  rows=1 loops=1)
      ->  Index Scan using vsn_idx on dwhinv  (cost=0.00..302591122.05    rows=267473826 width=12) (actual time=5798.912..5798.912 rows=1 loops=1)
            Index Cond: ((dwhinv___rfovsnide)::text > '201212_cloture'::text)
    Total runtime: 5799.141 ms
    
  • default_statistics_target = 200;

  • postgresql 版本 8.4

  • 使用的索引:

    CREATE INDEX vsn_idx
       ON dwhinv
       USING btree (dwhinv___rfovsnide);
    

计划仅从 5798.912 开始! 仅解释不到 1 毫秒,所以这不是计划选择的时间。 该列有 26 个不同的值。 该指数已 重新创建。

可能是什么问题?

【问题讨论】:

  • 查询和计划不匹配。你确定你发布了什么?
  • 已更正,我确实错过了复制粘贴
  • 统计数据相差很大。是vacuum analyze之后的计划吗?
  • 您的查询不返回该列的不同值。它只返回 first 值
  • 是的,这个查询是我们快速区分程序的一个子部分。每次我要求下一个值,直到我发现没有一个比先例更大

标签: postgresql delay sql-execution-plan


【解决方案1】:

感谢您的评论和 pgperf 邮件列表,我们发现了问题。

计划开始时的这个延迟是从索引中获取第一行的时间,所以它真的与索引读取有关。

我的索引是新鲜的,我的真空也是。 但是我们有一些查询IDLE in transation不允许真空来完成这项工作。

解释:

给定一个包含数百万行的表 MY_TABLE,由 DATA_VERSION 列(每列 1000 万行)和 DATA_VERSION 列上的​​索引平均分配

-> 第 1 步我播放一个停留在IDLE in transation

的查询

-> 第 2 步我 删除 MY_TABLE 中 DATA_VERSION = 100 和 200 的所有行

-> STEP 3 我使用 vacuum :由于 STEP 1 仍然 IDLE in transation

,vacuum 无法删除版本为 100 和 200 的行上的引用

-> 第 4 步我 查询 MY_TABLE 使用 DATA_VERSION 上的索引 获取所有 DATA_VERSION

-> 索引查看版本 100,尝试获取第一行 以确保它在表格中可见......它不是,再试一次与 ALL OTHER ROW ... 都消失了。表上的全部数据都被读取了......很多秒的io都丢失了

解决方案:避免步骤 1 永远停留以允许从索引中取消引用版本 100 和 200

【讨论】:

    猜你喜欢
    • 2014-04-15
    • 1970-01-01
    • 2019-04-01
    • 2020-02-07
    • 2016-06-20
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 2014-12-06
    相关资源
    最近更新 更多