使用简单的PostgreSQL 8.4.4在Centos 5.5上查询速度极慢

我看到的奇怪和极其缓慢的IO模式是( iostat -dxk 1 /dev/xvdb1 ):

 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.00 0.99 0.99 7.92 3.96 12.00 1.96 2206.00 502.00 99.41 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 100.40 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 100.40 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.00 0.99 0.00 3.96 0.00 8.00 0.99 2220.00 1004.00 99.41 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 1.00 0.00 0.00 100.40 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.99 0.99 0.00 7.92 0.00 16.00 1.14 2148.00 1004.00 99.41 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 2.01 0.00 0.00 100.40 Device: rrqm/s wrqm/sr/sw/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util xvdb1 0.00 0.00 1.00 1.00 4.00 8.00 12.00 2.01 1874.00 502.00 100.40 

我不知道为什么磁盘利用率和等待率如此之高,读写速度如此之低。 这可能是什么原因?

被查询的表只有几个varchar列,其中之一是last_name,索引(实际上lower(last_name)被索引)。 查询本身很简单:

 SELECT * FROM consumer_m WHERE lower(last_name) = 'hoque'; 

以下是解释输出:

  QUERY PLAN ------------------------------------------------------------------------------------------------- Bitmap Heap Scan on consumer_m (cost=2243.90..274163.41 rows=113152 width=164) Recheck Cond: (lower((last_name)::text) = 'hoque'::text) -> Bitmap Index Scan on consumer_m_last_name_index (cost=0.00..2215.61 rows=113152 width=0) Index Cond: (lower((last_name)::text) = 'hoque'::text) 

还要注意数据库在auto_vacuum上,所以没有进行明确的真空/分析。

您的设备是/dev/xvdb1意味着您正在Xen下运行。 你的存储如何configuration? 底层设备是否存在竞争, iostat如何看待这个问题

除非你能够消除这种可能性,否则我将指出那些performance糟糕的旋转微调。

基本上,解决像这样的性能问题的整体方法是考虑可能出现瓶颈的所有层,然后devisetesting以消除每个层,直到您隔离问题。

这里有一些build议,或多或less是随机的:

  1. 在CentOS中,默认情况下Autovacum没有打开。 有多个设置你必须设置启用它。 仔细检查真空过程实际运行。 很容易错过所需的设置之一。

  2. 请注意,您必须为该查询执行第二个筛选步骤,根据回复的内容,这可能很昂贵。 我会考虑一个索引,如:

    CREATE INDEX consumer_m_lower_last ON consumer_m(lower(last_name));

    这将匹配您的查询,并删除重新检查。

  3. 另外,正如mattdm指出的那样,在虚拟环境中不能信任iostat。

  4. 如果您在XEN环境中遇到IO问题,您应该检查http://lonesysadmin.net/2008/02/21/elevatornoop/ 。 电梯设置可以产生影响,但不是这么大。

  5. 底层磁盘是否使用LVM快照? 从pipe理angular度来看,这是非常有用的,但它可能会影响IO性能。 如果您正在使用的块设备是快照,并且已经获取了块设备的快照,则情况也是如此。

我怀疑这是PostgreSQL的问题,更可能只是磁盘IO的一个问题。 正如来自另一个答案的评论所提到的,如果它是一个磁盘IO问题,你真的应该从Dom0来衡量,这样你就可以看到发生的一切。

我有一个非常类似的问题,而且事实certificate是磁盘控制器的问题。 非常慢的磁盘访问导致系统在等待磁盘IO时出现瓶颈(显示为非常高的平均负载和等待时间,但也导致进程等待磁盘消耗更多的CPU,结果是内核没有正确识别控制器,而是重新回到了旧的IDE控制器,而不是一个快速的SATA控制器。

修复是用引导

 hda=noprobe hda=none 

在/etc/grub.conf中的内核string的末尾。 (当然,添加你所有的磁盘,ala: hdc=noprobe, hdc=none, hdd= …)