???? 之前在公司开发内部信息化系统,碰到了一个很悲剧事情。项目在测试环境运行没问题,上到正式环境,访问就卡住不动了。检查才发现那条查询的SQL的问题。因为一条SQL涉及了十几张表,left join的,inner join的,多表查询的,各种关联交杂在一起,整条SQL语句二三十行,放到plsql里面整整一页。可能由于这种关联性的东西太多,导致数据库执行查询的时候出现卡死的情况。测试环境的数据库是从正式环境中备份过去的,数据是一样的,而且都是同一台服务器的oracle,但实例名是不同的。最后使用了添加 /*+ ordered */? 解决了查询卡死的问题。
?
?????ORDERED提示强制Oracle按照From子句中表出现的顺序进行表连接。
?????通过ORDERED提示,可以避免CBO SQL解析过程中的表连接评估,从而避免Oracle产生错误的执行计划,或者强制Oracle按照我们指定的方式执行。在很多时候,当我们清楚地了解数据结构和数据分布之后,就可以通过ORDERED提示来提高SQL性能。
?????如下例:
SELECT /*+ ordered */ COUNT (*)FROM t_middle, t_small, t_maxWHERE t_small.object_id = t_middle.object_idAND t_middle.object_id = t_max.object_id;
?
最后发现数据库查询优化的问题,
where …… and rl.date_value >= to_date(tt.month,'yyyy-MM') and rl.date_value < add_months(to_date(tt.month,'yyyy-MM'),1) ……
??
where …… and to_char(rl.date_value,'yyyy-mm') = tt.month ……
?上面和下面这两天sql语句都是查询rl.date_value的时间在tt.month这个月份所有有关记录。。
通过大于或等于第一天并且小于第二个月的最后一天的这种方式,性能消耗极大。用第二种方式时间节省3倍以上。本来执行需要10秒多,修正后,大约一秒多就OK了。