Oracle:同一服务器上的数据库之间性能差异300倍

时间:2010-07-02 12:15:37

标签: performance oracle

我正在使用oracle 9.2.0.3.0服务器上的新数据库和旧数据库。

对新数据库中的表的查询比对旧数据库中的表的相同查询慢约300倍。

这些数据库非常相似,但存在一些差异:

我在旧版中测试的表有一个CHAR列(索引)和12个NUMBER列。 我在新表中测试的表有一个NUMBER列(索引)而不是CHAR列,13个NUMBER列和10个新的VARCHAR2列,大小限制为40-100。 两个表都以相同的方式编制索引(除了列的类型,然后......)

这两个表都有大约1900000条记录。 我的查询在两种情况下获得相同的执行计划(使用索引,没有完整扫描) 数据库位于单独的表空间中,但位于同一磁盘上。 旧表空间的使用率约为70%,新的表空间为94%,否则设置相同(据我所见)。 表空间中的碎片并不坏,但旧的碎片更糟糕(是的!) 由于新表有更多列,因此它使用的块比旧表多三倍。

关于如何进行的任何想法?

更新1:在新数据库上运行10次查询后,速度降低了大约80倍。改进!但是仍然没有解决。

更新2:由于列类型更改,查询会略有不同。首先是旧的(快)然后是新的(慢80-300倍)。

SELECT fhin, SUM(cost) 
FROM olddb.oldtable 
WHERE month in ('1004 ') AND fhin IN ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '22', '23', '24', '25', '26', '27', '28', '29', '30', '40', '99') 
GROUP BY fhin

SELECT fhin, SUM(cost) 
FROM newdb.newtable 
WHERE month IN (201004) AND fhin IN ('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '22', '23', '24', '25', '26', '27', '28', '29', '30', '40', '99') 
GROUP BY fhin;

请不要问为什么查询看起来像它,它不是我的; - )

更新3:使用旧查询解释统计信息:

execution schema (my translation to English)
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=CHOOSE
1    0   SORT (GROUP BY)
2    1     TABLE ACCESS (BY INDEX ROWID) OF 'OLDTABLE'
3    2       INDEX (RANGE SCAN) OF 'OLDTABLE' (NON-UNIQUE)

Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
    182  consistent gets
    101  physical reads
      0  redo size
    903  bytes sent via SQL*Net to client
    398  bytes received via SQL*Net from client
      3  SQL*Net round trips to/from client
      1  sorts (memory)
      0  sorts (disk)
     28  rows processed

解释新查询的统计信息:

execution schema (my translation)
----------------------------------------------------------
0      SELECT STATEMENT Optimizer=CHOOSE (Cost=36 Card=30 Bytes=360)
1    0   SORT (GROUP BY) (Cost=36 Card=30 Bytes=360)
2    1     TABLE ACCESS (BY INDEX ROWID) OF 'NEWTABLE' (Cost=11 Card=13857 Bytes=166284)
3    2       INDEX (RANGE SCAN) OF 'NEWTABLE' (NON-UNIQUE) (Cost=1 Card=22502)

Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
  11019  consistent gets
  11018  physical reads
      0  redo size
    906  bytes sent via SQL*Net to client
    398  bytes received via SQL*Net from client
      3  SQL*Net roundtrips to/from client
      1  sorts (memory)
      0  sorts (disk)
     28  rows processed

我猜他们毕竟不是那么相似。有什么想法吗?

更新4:感谢所有精彩的帮助!问题仍未解决,但我的客户在接下来的两周内无法使用。我会尝试一切,然后再回到这里进行更新!

更新5:我回到了网站!我运行了A. Musch建议的聚类因子分析,发现了这个:

Table   Clustering Factor   Rows    Blocks
Old     12633               1930000 12645
New     938379              1890000 39677

我猜测问题是我们在新数据库中有一个糟糕的集群因素。关于如何解决这个问题的任何想法或链接?

更新6:感谢Adam的提示,我发现了有关Oracle B树索引和聚类因子http://richardfoote.files.wordpress.com/2007/12/index-internals-rebuilding-the-truth.pdf的文章,并按照说明通过重新排序表来优化聚类因子索引列。问题解决了!

5 个答案:

答案 0 :(得分:2)

您是否注意到错误查询正在执行好查询的I / O的50-100倍?

Fast Version I/O:
    182  consistent gets 
    101  physical reads 

Slow Version I/O
  11019  consistent gets 
  11018  physical reads 

我很想看到每个系统的驱动索引(一个月的?)的聚类因子(ALL_INDEXES.CLUSTERING_FACTOR)以及它与行数(COUNT(*))和块的比较来自基础表的(DBA_SEGMENTS.BLOCKS)。

答案 1 :(得分:0)

新数据库的统计信息是最新的吗?

答案 2 :(得分:0)

1.它一直慢300倍?或者旧的数据库是否已经缓存了所有内容?

2.另外,你说了一些令我惊讶的事情。

  

数据库是分开的   表空间,但在同一个磁盘上。

当然,它们位于不同的表空间中 - 它们必须是。你的意思是说别的吗?

3.两个数据库运行时是否进行了比较?换句话说,旧数据库是否具有相同数量的可用资源?您是否已将所有内存分配给旧数据库并为新数据库留下任何内容?我会关闭旧数据库,为新服务器启动内存,然后再次尝试比较。

答案 3 :(得分:0)

如果查询相同,列类型是否会更改索引数据的隐式to_char()?这可以减慢很多事情;虽然如果执行计划表明它仍在使用索引,那么这似乎不太可能。听起来你在一个表上做了一个简单的查询,但如果没有,是否有从索引(数字)列到另一个表中的一个仍然是char的连接?我原本以为更改列类型至少需要对查询进行一些调整。

答案 4 :(得分:0)

fhin是否更改了类型的列?在这种情况下,仍然将值与字符进行比较的列表将解释该问题。

相关问题