很惊奇,为什么分析后优化器就能找出问题所在,此时焦点都集中在trace文件了;分析trace文件,发现如下信息;
SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) opt_param('parallel_execution_enabled', 'false') result_cache */ COUNT(C1) FROM (SELECT /*+ qb_name("innerQuery") NO_INDEX_FFS( "ORDERS") */ 1 AS C1 FROM "ORDERS" SAMPLE BLOCK(56.8182, 2) SEED(1) "ORDERS") innerQuery SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) opt_param('parallel_execution_enabled', 'false') result_cache */ COUNT(C1) FROM (SELECT /*+ qb_name("innerQuery") INDEX_FFS( "ORDERS" "IDX_ORDERS_DT") */ 1 AS C1 FROM "ORDERS" SAMPLE BLOCK(59.5238, 2) SEED(1) "ORDERS" WHERE ( "ORDERS".ORDER_DATE IS NOT NULL)) innerQuery SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) opt_param('parallel_execution_enabled', 'false') result_cache */ COUNT(C1) FROM (SELECT /*+ qb_name("innerQuery") NO_INDEX_FFS( "ORDERS") */ 1 AS C1 FROM "ORDERS" SAMPLE BLOCK(56.8182, 2) SEED(1) "ORDERS" WHERE ("ORDERS"."ORDER_DATE">=TRUNC(SYSDATE@!,'fmdd'))) innerQuery SELECT /* DS_SVC */ /*+ dynamic_sampling(0) no_sql_tune no_monitoring optimizer_features_enable(default) opt_param('parallel_execution_enabled', 'false') result_cache OPT_ESTIMATE(@"innerQuery", TABLE, "ORDERS", SCALE_ROWS=3.545138895e-05) */ C1, C2, C3 FROM (SELECT /*+ qb_name("innerQuery") INDEX( "ORDERS" "IDX_ORDERS_DT") */ COUNT(*) AS C1, 4294967295 AS C2, COUNT(*) AS C3 FROM "ORDERS" "ORDERS" WHERE ("ORDERS"."ORDER_DATE">=TRUNC(SYSDATE@!,'fmdd'))) innerQuery /* SQL Analyze(156,0) */ select * from orders where order_date>=trunc(sysdate,'DD')从trace文件分析得出,oracle做了如下的操作:
动态采样分析全表数据(无索引);
动态采样分析表中非空数据(无索引);
用全表扫描的方式动态采样分析相关的数据;
用索引扫描的方式动态采样分析相关的数据;
对比旧的和新的执行计划;
Oracle对比旧的和新的执行计划后,将消耗小的执行计划信息保存到SQL profile中。
优化器的问题通常优化器相信:
数据值分布均匀(比如假设:表列数据中,数值2比数值5一样使用频繁);
数据行分布均匀(比如假设:没有物理cluster或者数据排序);
对于范围数据是连续的,没有漏缺。
优化器信任收集的统计信息,这些信息包括表行记录数,distinct value,max/min value,直方图信息;换一种通俗的说法,统计信息捕获了表整体形状数据,但有些低级别的信息丢失了。这种分析对于大多数数据来说往往工作得很好,但实际情况中,不可避免的有违反规则的例外,比如对于一张大表,98%的数据可能以随机的方式分配在整个段中(segment),剩余的2%的数据可能只集中在几个数据块中;不幸的是收集统计信息时没有记录这些细节;这就引发一个问题,已经有的统计信息不能完全有效的帮助优化器生成正确的执行计划,所以到了这里问题转变为什么可以弥补或纠正这些信息,让优化器面对这种特定的SQL时可以评估正确,生成好的执行计划。
什么是SQL Profile通过上面的实验大体将SQL Profile定义为:
为特定SQL创建和保存执行计划信息;
使用实际运行时的数据来帮助优化器为特定的SQL评估和生成更好的执行计划;