您好,欢迎访问一九零五行业门户网

被Oracle全局临时表坑了

今天凌晨4点多钟,在客户现场的负责人打电话给我,说很奇怪,下载功能时快时慢。此下载功能非常复杂,之前一直是我优化,在半梦半
今天凌晨4点多钟,在客户现场的负责人打电话给我,说很奇怪,下载功能时快时慢。此下载功能非常复杂,之前一直是我优化,在半梦半醒中打开电脑,通过远程看着现场同事在pl/sql developer中操作。执行同一条sql,时快时慢,快的时候大概0.6s,慢的时候超过1分钟。
    这条sql有调用一个函数,功能是动态生成接近200条查询语句,sql中都是有绑定变量的。是现场的测试环境,刚刚部署,心想应该不是数据库负载所致。
    1. 抓取数据库awr报告,完全没有压力,数据库服务器配置都是杠杠的。此刻心里有点乱,头一次遇到这种问题。现场9点钟要跟客户演示,此时已经快5点钟了。
    2. 神器出场,打算用10046 trace定位到到底是那条sql有问题,trace了多次,只有一次是慢的。期间也有插曲,现场不太会用sqlplus,交互化了很多时间。从众多的sql中抽丝剥茧,终于定位到sql,对比是:
select distinct d.id, d.table_name, dct.column_name, gg.data_type,
  gg.techparam_name,dct.sort_no from gg_classify_techparam dct, gg_techparam
  gg, gg_classify d, rel_oid_classify t where dct.techparam_id = gg.id and
  d.id = dct.classify_id and t.classify_id = d.id
call    count      cpu    elapsed      disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
parse        0      0.00      0.00          0          0          0          0
execute      1      0.00      0.00          0          0          0          0
fetch        2    61.00      61.04          0  25968917          0        156
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3    61.00      61.04          0  25968917          0        156
call    count      cpu    elapsed      disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
parse        0      0.00      0.00          0          0          0          0
execute      1      0.00      0.00          0          0          0          0
fetch        2      0.80      0.81          0      32461        0        156
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.80      0.81          0      32461        0        156
  3. 分析问题,第一感觉是sql逻辑是否有问题,可惜10046里面没有trace到执行计划,不过看逻辑读,慢的那次应该是产生了笛卡尔积。经过简单的检查,sql逻辑没有问题,人的第一感觉不一定靠谱。
  4. 我在想是什么导致执行计划不准呢,猛然想起rel_oid_classify是全局临时表,快速的想到一种可能,rel_oid_classify的统计信息不准导致,通过user_tables查看这张表是没有统计信息的。那就是每次执行都动态采集啰,在oracle 11g中执行autotrace,发现level=2,我想试试把动态采样的级别,说干就干。
 select /*+ dynamic_sampling(t 10) */distinct d.id, d.table_name, dct.column_name, gg.data_type,
  gg.techparam_name,dct.sort_no from gg_classify_techparam dct, gg_techparam
  gg, gg_classify d, rel_oid_classify t where dct.techparam_id = gg.id and
  d.id = dct.classify_id and t.classify_id = d.id;
发给开发人员,,修改相关函数。增量后,多次测试后发现问题解决了。此时已经快7点了,天已经大亮,我有点倦意,但无法再次入睡。
      总结:对于这次临时表的问题,我想问题在于采样率低了以后造成的恶果。对于全局临时表要注意两点,一是要锁定临时表收集统计信息的功能,因为你收集的统计信息肯定是错的;二是使用它时最好是使用动态采用。学习知识,基础很重要。
在centos 6.4下安装oracle 11gr2(x64)
oracle 11gr2 在vmware虚拟机中安装步骤
debian 下 安装 oracle 11g xe r2
本文永久更新链接地址:
其它类似信息

推荐信息