PostgreSQL:查询计划在开始时延迟

时间:2014-04-17 15:48:32

标签: postgresql delay sql-execution-plan

我们在巨大的桌子上使用单列索引来尝试快速 '选择不同的'在专栏上。

这曾经工作得很好,但......已经不行了。我们不知道是什么 发生了。

以下是事实:

  • 请求:

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

模仿'不同,我们多次播放此查询,每次更改dwhinv___rfovsnide值以获取下一个值。

正常查询时间小于1毫秒。

  • 计划:

    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个不同的值。 该指数一直是 新鲜的重建。

可能是什么问题?

1 个答案:

答案 0 :(得分:0)

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

计划开始时的延迟是从索引获取第一行的时间,因此它实际上与索引读数有关。

我的索引很新鲜,我的真空也是。 但是我们有一些疑问 IDLE in transation 女巫不允许真空做这项工作。

解释:

给出一个包含数百万行的表MY_TABLE,同样按列DATA_VERSION(每个10百万)重新分配,并在DATA_VERSION列上进行索引

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

的查询

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

- >步骤3我使用 vacuum :vacuum cant删除对版本为100&的行的引用200因为STEP 1仍然 IDLE in transation

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

- > 索引查看版本100 ,尝试获取第一行以确保它在表格中可见...它不是再次尝试使用ALL OTHER ROW。 ......一切都消失了。桌面上的完整数据已经被读取了......很多秒钟的io都丢失了

解决方案:避免STEP 1永久停留以允许真空解除引用版本100&索引200