1. 程式人生 > >基於成本的優化--CBO

基於成本的優化--CBO

優化 CBO SQL語句 執行計劃

選擇CBO的優化方式 默認條件下,CBO將SQL語句的吞吐量作為優化目標 三種不同的優化方式 ALL_ROWS :該優化方式是Oracle的默認模式,優化目標是實現查詢的最大吞吐量 FIRST_ROWS_n:該優化方式使用CBO的成本優化輸出查詢的前n行數據,目標是以滿足快速相應的查詢需求, FIRST_ROWS :該方式是FIRST_ROWS_n優化方式的老版本,作用是使用CBO的成本優化盡快輸出查詢的前幾行數據,滿足最小相應時間的需求 查詢當前數據庫的CBO優化方式 show parameter optimizer_mode 在實例級設置優化方式 alter system set optimizer_mode = FIRST_ROWS_10 scope=spfile 在會話級設置優化方式 alter session set optimizer_mode=ALL_ROWS 會話級上設置優化方式必須使用hint提示 select /*+first_rows_10*/ ename,sal,mgr from scott.emp 優化器工作過程 步驟 1.SQL轉換 在CBO優化中,一個SQL語句往往被轉換成另一種表達形式,這個轉換的基礎是CBO認為轉換後的查詢會更有效 2.確定訪問路徑 一個SQL查詢中對數據的訪問的路徑要根據訪問這些數據消耗的資源來判斷,在多個查詢路徑中選擇計算成本最小的一個。 3.確定聯結方式 在SQL語句中涉及多個表時,CBO會根據統計數據以及表的鍵的信息來選擇連接方式,在多個連接方法中選擇計算成本最低的一個作為最佳連接方法 4.確定聯結次序 CBO會對不同的連接次序中進行計算以選擇最好的執行計劃。 自動統計數據 查看GATHER_STATS_JOB狀態 select job_name,state,owner from dba_scheduler_jobs; 通過數據字典DBA_TABLES查詢用戶SCOTT擁有表的統計分析情況 select last_analyzed,table_name,owner,num_rows,sample_size from dba_tables where owner='SCOTT' 手動統計數據庫數據 DBMS_STATS 存儲過程 GATHER_DATABASE_STATS 為全庫中的表統計數據 GATHER_SCHEMA_STATS 為某個模式統計數據 GATHER_TABLE_STATS 為某個特定的表統計數據 GATHER_INDEX_STATS 為某個索引表統計數據 上述統計數據保存在 DBA_TAB_STATISTICS 和 DBA_TAB_COL_STATISTICS 為模式SCOTT的所有表統計數據 execute DBMS_STATS.GATHER_SCHEMA_STATS(ownname=>'SCOTT'); 驗證模式SCOTT的數據統計成功 select last_analyzed,table_name,owner,num_rows,sample_size from dba_tables where owner='SCOTT' 為模式SCOTT用戶的表EMP統計數據 execute DBMS_STATS.GATHER_TABLE_STATS('SCOTT','EMP'); 為DEPT的索引統計數據 execute DBMS_STATS.GATHER_INDEX_STATS('SCOTT','PK_DEPT') 手工收集數據庫級別的統計數據-----需要對初始化參數JOB_QUEUE_PROCESSES設置一個非0值 execute DBMS_STATS.GATHER_DATABASE_STATS(estimate_percent=>null) 查詢表的統計數據 DBA_TAB_STATISTICS 查詢表的列的統計數據 DBA_TAB_COL_STATISTICS 統計OS數據 DBMS_STATS.GATHER_SYSTEM_STATS SYS.AUX_STAST$ 無負載方式下收集10分鐘的系統統計數據 execute DBMS_STATS.GATHER_SYSTEM_STATS('NOWORKLOAD',10) 收集系統統計數據 execute DBMS_STATS.GATHER_SYSTEM_STATS('start') execute DBMS_STATS.GATHER_SYSTEM_STATS('stop') 每三分鐘執行一次 查詢統計的系統數據 select * from SYS.AUX_STAST$; 手工統計字典數據---具備SYSDBA權限 收集固定字典表的統計數據 execute DBMS_STATS.GATHER_FIXED_OBJECTS_STATS; 收集數據字典表的統計數據 execute DBMS_STATS.GATHER_DIRECTORY_STATS; / 使用過程GATHER_SCHEMA_STATS統計數據字典數據 execute DBMS_STATS.GATHER_SCHEMA_STATS('sys') 主動優化SQL語句 SQL語句優化工具 1.使用EXPLAN FOR 指令 utlxplan.sql 執行腳本---生成PLAN_TABLE表 @?/rdbms/admin/utlxplan.sql 通過EXPLAIN PLAN FOR 指令分析SQL語句的執行計劃 explain plan for select count(*) from scott.emp; 查看表 PLAN_TABLE 中SQL語句執行計劃信息 col if for 999 col operation for a20 col options for a20 col object_name for a20 select id,operation,options,object_name,position from PLAN_TABLE OPERATION :為TABLEACCESS說明該步驟的行為是訪問表 OPTIONS :為FULL,說明全表掃描訪問表 OBJECT_NAME :說明行為的對象為表EMP 使用AUTOTRACE指令------SQL_TRACE=TRUE 設置參數 SQL_TRACE 啟動SQL語句追蹤 alter system set SQL_TRACE = TRUE; /* 選項 結果 SET AUTOTRACE ON 查詢輸出,解釋計劃,統計信息 SET AUTOTRACE OFF 關閉 AUTOTRACE SET AUTOTRACE ON EXPLAIN 查詢輸出,解釋計劃,沒有統計信息 SET AUTOTRACE ON EXPLAIN STAT 查詢輸出,解釋計劃,統計信息 SET AUTOTRACE ON STAT 查詢輸出,解釋計劃,統計信息 SET AUTOTRACE TRACE 解釋計劃,統計信息,生成結果但不顯示 SET AUTOTRACE TRACE EXPLAIN 只有解釋計劃,不生成結果 SET AUTOTRACE TRACE STAT 只有統計,生成結果但不顯示*/ 使用AUTOTRACE追蹤SQL語句執行計劃 set autotrace traceonly select count(*) from scott.emp

技術分享圖片

					recursive calls                       遞歸調用的次數
					db block gets                         讀數據塊的數量
					consistent gets                       總的邏輯I/O 
					physical reads                        物理I/O 
					redo size                             重做數量
					bytes sent via SQL*Net to client      SQL*Net通信
					bytes received via SQL*Net from client
					SQL*Net roundtrips to/from client     
					sorts (memory)                        內存排序統計
					sorts (disk)                          磁盤排序統計
					rows processed                        被檢索的行數
				關閉AUTOTRACE
					set autotrace OFF
					
					
			啟動 SQL Trace的前提
			   1.statistics_level: TYPICAL / ALL
			   						BASE 

			   2.timed_statistics:	TRUE   -----BASE
			   						False	-----TYPICAL / ALL

			   3.user_dump_dest:	該參數存儲SQL語句的追蹤文件。

			   (max_dump_file_size)

			啟動SQL Trace追蹤
				實例級啟動SQL Trace追蹤
					alter system set SQL_TRACE=TRUE

				會話級啟動SQL Trace追蹤
					alter session set SQL_TRACE=TRUE
					/
					begin
					sys.dbms_session.set_sql_trace(TRUE);
					end;
					
			使用 TKPPOF 解釋 SQL Trace文件
				
				執行sql查詢
				使用TKPPOF工具格式化SQL追蹤文件
					TKPPOF  xxxxxxxx.trc xxxx.txt sys=no
					
				格式化參數的含義
				count	:不同執行階段所讀取的數據塊數量
				cpu     :不同執行階段鎖消耗的CPU時間,單位是秒
				elapsed :執行用掉的時間
				disk    :物理磁盤數據讀操作數目
				query   :一致的緩沖區讀取數量
				current :數據庫塊讀取的數量
				call    :該參數說明SQL語句的不同執行階段 										


消除子查詢優化SQL語句
	對查詢用戶scott的emp表進行嵌套子查詢
		select * 
		from scott.emp e1
		where e1.sal>
		(select avg(sal)
			from scott.emp e2
			where e2.deptno=e1.deptno)
	開啟AUTOTRACE功能
		set autotrace traceonly
	跟蹤SQL語句的執行
		select * 
		from scott.emp e1
		where e1.sal>
		(select avg(sal)
			from scott.emp e2
			where e2.deptno=e1.deptno)

技術分享圖片

	跟蹤改寫的SQL語句
	  使用聯機視圖改寫子查詢
		select * from scott.emp e1,(select e2.deptno deptno ,avg(e2.sal) avg_sal 
		from scott.emp e2 group by deptno ) dept_avg_sal
		where e1.deptno = dept_avg_sal.deptno
		and e1.sal > dept_avg_sal.avg_sal

技術分享圖片

	被動優化SQL語句
		使用分區表
		    使用表和索引壓縮
		            創建壓縮表
					create table compress_emp 
					compress 
					tablespace users 
					as select * from scott.emp

				查詢是否成功創建壓縮表	compress_emp
					select table_name,tablespace_name,compression
					from user_tables
					where table_name like 'COMPRESS%';

				創建壓縮索引
					create index compress_emp_ename_idx
					on compress_emp(ename)
					compress;
					
		保持CBO的穩定性
			1.創建存儲大綱的前提
				初始化參數
					QUERY_REWRITE_ENABLED = TRUE
					STAR_TRANSFORMATION_ENABLED = TRUE

				驗證系統師傅具備創建存儲大綱的前提
					show paameter QUERY_REWRITE_ENABLED;
					show paramter STAR_TRANSFORMATION_ENABLED;
					show parameter optimizer_features_enable;

			2.創建存儲大綱
					創建數據庫級的存儲大綱
						alter system set create_stored_outlines = TRUE

					創建會話級的存儲大綱
						alter session set create_stored_outlines = TRUE

						為特定SQL語句創建存儲大綱
							create outline emp_outline
							on
							select * 
							from scott.emp
							tablespace oltbs;

						查詢EMP_OUTLINE創建信息
							select ol_name,sql_text,creator,timestamp
							from ol$
							where ol_name like 'EMP%'

						查詢Oracle自動生產的存儲大綱的名字
							set lines 120
							select ol_name,sql_text
							from ol$

			3.刪除存儲大綱
					刪除存儲大綱-----sysdba
						drop outline emp_outline
						
			4.啟用存儲大綱
					修改參數 USE_STORED_OUTLINES 為TRUE
						alter system set USE_STORED_OUTLINES= TRUE


基於成本的優化--CBO