SQL?優(yōu)化作為DBA日常主要工作內(nèi)容,分析SQL的執(zhí)行計劃浆竭,是必須要掌握的知識點挪哄。執(zhí)行計劃體現(xiàn)了SQL在數(shù)據(jù)庫中的執(zhí)行方式吧秕,SQL語句按照什么樣的方式執(zhí)行,是由優(yōu)化器決定的迹炼。達(dá)夢數(shù)據(jù)庫也是一樣砸彬,SQL語句是由優(yōu)化器設(shè)計執(zhí)行方式的。達(dá)夢數(shù)據(jù)庫提供了2個命令來進行分析SQL的執(zhí)行計劃斯入,分別為explain和explain for砂碉,下面我們分別進行介紹。
1?刻两、使用EXPLAIN分析執(zhí)行計劃
達(dá)夢數(shù)據(jù)庫提供explain命令查看SQL的執(zhí)行計劃增蹭,命令使用語法格式為:EXPLAIN <SQL 語句>;
執(zhí)行計劃顯示方式與Oracle類似,執(zhí)行計劃的執(zhí)行順序也是與Oracle類似磅摹,如果能看懂Oracle數(shù)據(jù)庫的執(zhí)行計劃滋迈,看達(dá)夢數(shù)據(jù)庫的執(zhí)行計劃就非常容易了霎奢,主要的難度就是達(dá)夢數(shù)據(jù)庫SQL執(zhí)行計劃的操作符與Oracle是不一樣的,達(dá)夢數(shù)據(jù)庫也是提供了V$SQL_NODE_NAME視圖饼灿,供大家查看每個操作符的含義幕侠,當(dāng)然,也可以直接去官方手冊《DM8系統(tǒng)管理員手冊》-附錄4執(zhí)行計劃操作符章節(jié)來查每個操作符的含義碍彭。達(dá)夢數(shù)據(jù)庫SQL執(zhí)行計劃的執(zhí)行過程為:控制流從上到下傳遞晤硕,數(shù)據(jù)流從下到上傳遞。
1?#NSET2:?[0,?16,?9]
2???#PRJT2:?[0,?16,?9];?EXP_NUM(2),?IS_ATOM(FALSE)
3?????#NEST?LOOP?INDEX?JOIN2:?[0,?16,?9]
4???????#CSCN2:?[0,?4,?5];?INDEX33555535(B)
5???????#SSEK2:?[0,?4,?0];?SCAN_TYPE(ASC),?IDX_T1_C1?(A),
SCAN_RANGE[T2.D1,T2.D1]
例如庇忌,如上的執(zhí)行計劃大致執(zhí)行流程如下:
1) CSCN2:?掃描 T2 表的聚集索引舞箍,數(shù)據(jù)傳遞給父節(jié)點索引連接;
2) NEST LOOP INDEX JOIN2:?當(dāng)左孩子有數(shù)據(jù)返回時取右側(cè)數(shù)據(jù)皆疹;
3) SSEK2:?利用 T2 表當(dāng)前的 D1 值作為二級索引 IDX_T1_C1 定位查找的 KEY疏橄,返回結(jié)果給父節(jié)點;
4) NEST LOOP INDEX JOIN2:?如果右孩子有數(shù)據(jù)則將結(jié)果傳遞給父節(jié)點 PRJT2墙基,否則繼續(xù)取左孩子的下一條記錄软族;
5) PRJT2:?進行表達(dá)式計算 C1+1, D2刷喜;
6) NSET2:?輸出最后結(jié)果残制;
7)?重復(fù)過程 1) ~ 4)直至左側(cè) CSCN2 數(shù)據(jù)全部取完。
2?掖疮、使用EXPLAIN FOR分析執(zhí)行計劃
EXPLAIN FOR?語句也用于查看 SQL語句的執(zhí)行計劃初茶,不過執(zhí)行計劃以結(jié)果集的方式返回。EXPLAIN FOR 顯示的執(zhí)行計劃信息相比于EXPLAIN更加豐富浊闪,除了常規(guī)計劃信息恼布,還包括創(chuàng)建索引建議、分區(qū)表的起止分區(qū)信息等搁宾。重要的是折汞,語句的計劃保存在數(shù)據(jù)表中,方便用戶隨時查看盖腿,進行計劃對比分析爽待,可以作為性能分析的一種方法。
語法格式為:EXPLAIN [AS 計劃名稱] FOR <SQL 語句>;
需要注意的是翩腐,explain for將語句的執(zhí)行計劃保存在"SYSDBA"."##PLAN_TABLE"表中鸟款,而這個表是個臨時表,且是會話級的茂卦,如果需要永久保存執(zhí)行計劃何什,需要將該表中的信息轉(zhuǎn)儲到其他永久表中,如下是該表的創(chuàng)建語句等龙,從語句末尾可以看到給表的屬性处渣。
CREATE?GLOBAL?TEMPORARY?TABLE?"SYSDBA"."##PLAN_TABLE"
(
"PLAN_ID"?INT,
"PLAN_NAME"?VARCHAR(128),
"CREATE_TIME"?DATETIME(6),
"LEVEL_ID"?INT,
"OPERATION"?VARCHAR(30),
"TAB_NAME"?VARCHAR(128),
"IDX_NAME"?VARCHAR(128),
"SCAN_TYPE"?VARCHAR(20),
"SCAN_RANGE"?VARCHAR(128),
"ROW_NUMS"?BIGINT,
"BYTES"?INT,
"COST"?BIGINT,
"CPU_COST"?BIGINT,
"IO_COST"?BIGINT,
"FILTER"?VARCHAR(1000),
"JOIN_COND"?VARCHAR(1000),
"ADVICE_INFO"?VARCHAR(1000),
"PSTART"?INT,
"PSTOP"?INT)
ON?COMMIT?PRESERVE?ROWS?STORAGE(ON?TEMP);
ON COMMIT PRESERVE ROWS?:指定臨時表是會話級的伶贰,會話結(jié)束時會清空表。
https://eco.dameng.com