February 2012
M T W T F S S
« Aug    
 12345
6789101112
13141516171819
20212223242526
272829  

一样的delete语句,不一样的执行时间

Kaya 发表于 os2ora.com

一个delete语句,在”同样”的环境下执行两遍。第一次花了16分钟,第二次花了24分钟。

这条delete语句是这样子的:

DELETE FROM T A
 WHERE EXISTS (SELECT 1
          FROM T B
         WHERE B.KEY = A.KEY
           AND A.ROWID < B.ROWID);

在做delete之前,已经保证表A尽可能一致,两次delete都是以串行方式执行。在这个表上都没有索引存在。整个系统只有这个SQL在运行。

问题究竟出现在哪里呢?

先检查redo, undo还有logical reads, 看看是否存在不同:

Name First Second
redo size 11,104,438,044 11,104,338,924
session logical reads 28,549,120 28,544,934
redo entries 23,921,147 23,920,329
undo change vector size 7,803,284,388 7,803,283,836

可以看出,两次运行基本上产生的redo和undo和所要求的logical reads都是差不多一样的。

在检查其它性能数据的过程中,两者的物理IO有了明显的差别:

Name First Second
cell physical IO interconnect byte 19,284,271,104 27,067,580,416
physical IO disk bytes 19,284,271,104 27,067,580,416
physical read total bytes 14,780,686,336 22,563,995,648
physical write total bytes 2,251,792,384 2,251,792,384

明显地,第二次运行比第一次运行多了一半的读IO,这刚好与第二次运行的时间比第一次运行的时间多一半相吻合。

一个可能的解释在于buffer cache在两次运行开始时所处的状态不同。导致了第二次运行时没有充足的free buffer,从而进一步导致了buffer命中率的下降。这从下面关于buffer的一些性能指标值也可以看出:

Name First Second
hot buffers moved to head of LRU 1,366,782 2,379,131
free buffer inspected 2,784,972 3,761,837
free buffer requested 2,705,382 3,670,718
dirty buffers inspected 356,118 895,195

为了验证上面的结论,可以做两个测试,第一是在跑delete之前把buffer cache flush,第二是在跑delete之前把表A的数据加载进buffer cache。

当flush buffer cache后,delete花了17分钟。

当把数据加载进buffer cache后,delete花了8分钟。

这个例子最重要的一点在于说明了memory对OLTP系统性能的严重影响。这是与DSS系统存在明显区别的一个地方,也可以说是串行操作与并行操作的显著区别。对OLTP系统而言,SGA起着减少物理IO的作用。对SGA的有效管理与配置,影响着OLTP系统的性能。而对于DSS系统而言,PGA并不会减少扫描表的IO量。PGA里面的数据随着操作的完成而得以释放。

Note: 上面性能指标值来源于v$mystat视图。

1 comment to 一样的delete语句,不一样的执行时间

  • ignu

    为了验证上面的结论,可以做两个测试,第一是在跑delete之前把buffer cache flush,第二是在跑delete之前把表A的数据加载进buffer cache。

    当flush buffer cache后,delete花了17分钟。

    当把数据加载进buffer cache后,delete花了8分钟。

    这里表述有点不清。其中第一第二, 我想你要说的是, 第二次delete的时候分成两步
    一是在跑delete之前把buffer cache flush
    二是在跑delete之前把表A的数据加载进buffer cache(全表扫描一下)

    但还有一种情况我也遇到过,就是在做第二次delete的时候第一次的delete是commit还是rollback还是放在第一个session中既没有commit也没有rollback,这样也会导致第二次delete的时候导致需要从undo中取数据而变慢的。

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

您也可以使用微博账号登陆