国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

使用Explain進(jìn)行查詢及應(yīng)用優(yōu)化

2024-07-21 02:38:02
字體:
供稿:網(wǎng)友

  應(yīng)用的優(yōu)化不僅需要知道應(yīng)用作了什么,還必須知道應(yīng)用是如何工作的以及使用何種數(shù)據(jù)庫設(shè)計(jì)來支持,必須了解使用哪種類型的SQL語句,語句中表與視圖的結(jié)構(gòu)及與這些表相關(guān)的各類索引。 另外,優(yōu)化整個(gè)應(yīng)用系統(tǒng)可能并不是必需的,了解應(yīng)用的各個(gè)部分可以讓我們了解哪些部分是需要優(yōu)化的。我們將主要討論使用Oracle RDBMS提供的性能優(yōu)化工具進(jìn)行SQL級(jí)的優(yōu)化。
  
  EXPlain可以用來迅速方便地查出對(duì)于給定SQL語句中的查詢數(shù)據(jù)是如何得到的即搜索路徑(我們通常稱為access Path)。Access Path對(duì)性能會(huì)有非常大的影響。我們將會(huì)討論各種Access Path和使用的優(yōu)缺點(diǎn)。
  
  使用Explain
  使用Explain工具需要?jiǎng)?chuàng)建Explain_plan表,這必須先進(jìn)入相關(guān)應(yīng)用表、視圖和索引的所有者的帳戶內(nèi)。Oracle的介質(zhì)中包含有執(zhí)行此項(xiàng)工作的SQL源程序,例如:
  
  ORA_RDBMS: XPLAINPL.SQL (VMS)
  
  $ORACLE_HOME/rdbms/admin/utlxplan.sql (UNIX)
  
  這個(gè)SQL程序應(yīng)與catalog.sql在同一目錄,這個(gè)程序會(huì)創(chuàng)建一個(gè)名為plan_table的表,表結(jié)構(gòu)如下:
  
  Name Type
  
  STATEMEN_ID VARCHAR2(30)
  
  TIMESTAMP DATE
  
  REMARKS VARCHAR2(80)
  
  OperaTION VARCHAR2(30)
  
  OPTIONS VARCHAR2(30)
  
  Object_node VARCHAR2(128)
  
  Object_owner VARCHAR2(30)
  
  Object_name VARCHAR2(30)
  
  Object_instance NUMBER(38)
  
  Object_type VARCHAR2(30)
  
  Search_columns NUMBER(38)
  
  ID NUMBER(38)
  
  PARENT_ID NUMBER(38)
  
  POSITION NUMBER(38)
  
  OTHER LONG
  這里介紹一些我們將會(huì)討論的column的主要概念。假如需要每一個(gè)column的具體介紹,請看explain.doc文件。
  
  STATEMENT_ID:為一條指定的SQL語句確定特定的執(zhí)行計(jì)劃名稱。假如在EXPLAN PLAN語句中沒有使用SET STATEMENT_ID,那么此值會(huì)被設(shè)為NULL。
  
  OPERATION:在計(jì)劃的某一步驟執(zhí)行的操作名稱,例如:Filters,Index,Table,Marge Joins and Table等。
  
  OPTION:對(duì)OPERATION操作的補(bǔ)充,例如:對(duì)一個(gè)表的操作,OPERATION可能是TABLE ACCESS,但OPTION可能為by ROWID或FULL。
  
  Object_Owner:擁有此database Object的Schema名或Oracle帳戶名。
  
  Object_name:Database Object名
  
  Object_type:類型,例如:表、視圖、索引等等
  
  ID:指明某一步驟在執(zhí)行計(jì)劃中的位置。
  
  PARENT_ID:指明從某一操作中取得信息的前一個(gè)操作。通過對(duì)與ID和PARENT_ID使用Connect By操作,我們可以查詢整個(gè)執(zhí)行計(jì)劃樹。
  
  這個(gè)PLAN表一旦創(chuàng)建成功,用戶就可在應(yīng)用中使用EXPLAIN。使用語法如下:
  
  EXPLAIN PLAN [ SET STATEMENT_ID [=] < string literal > ]
  
  [ INTO < table_name > ]
  
  FOR < sql_statement >
  
  其中:
  STATEMENT_ID是一個(gè)唯一的字符串,把當(dāng)前執(zhí)行計(jì)劃與存儲(chǔ)在同一PLAN表中的其它執(zhí)行計(jì)劃區(qū)別開來。
  
  TABLE_NAME是plan表名,它結(jié)構(gòu)如前所示,你可以任意設(shè)定這個(gè)名稱。
  
  SQL_STATEMENT是真正的SQL語句。
  
  例如:
  
  EXPLAIN PLAN
  
  SET STATEMENT_ID=‘QUERY1’
  
  FOR
  
  SELECT
  
  FROM EMP
  
  WHERE DEPTNO=10;
  
  執(zhí)行后將會(huì)得到以下信息:
  
  operation 50 sUCceeded
  
  注重,假如在Explain語句中忽略INTO句,則EXPLAIN會(huì)使用PLAN_TABLE作為表名,我們可以用查詢plan table的方法來檢查執(zhí)行計(jì)劃,如:
  
  SELECT OPERATION, OPTIONS, OBJECT_NAME, OBJECT_TYPE, ID, PARENT_ID
  
  FROM PLAN_TABLE
  
  WHERE STATEMENT_ID=‘QUERY1’
  
  ORDER BY ID;
  
  將會(huì)返回如下:
  
  OPERATION OPTION Object_name Object_type ID Parent_ID
  
  TABLE ACCESS FULL EMP TABLE 1 1
  
  1 row selected
  
  這意味在這個(gè)查詢中將會(huì)使用全表掃描,假如在EMP表上沒有創(chuàng)建索引,對(duì)EMP的所有查詢都將使用全表掃描,但是假如在DEPTNO列上創(chuàng)建一個(gè)非唯一的索引:
  
  CREATE INDEX EMP_IDX ON EMP(DEPTNO);
  
  現(xiàn)在,假如我們重新解釋查詢:
  
  EXPLAIN PLAN
  
  SET STATEMENT_ID=’QUERY2’
  
  FOR
  
  SELECT *
  
  FROM EMP
  
  WHERE DEPTNO=10;
  
  然后檢查計(jì)劃表:
  
  SELECT OPERATION, OPTIONS, OBJECT_NAME,OBJECT_TYPE,ID,PARENT_ID
  
  FROM PLAN_TABLE
  
  WHERE STATEMENT_ID=‘QUERY2’
  
  ORDER BY IB;
  
  將返回:
  
  OPERATION OPTION Object_name Object_type ID Parent_ID
  
  TABLE ACCESS BY RAWID EMP TABLE 1
  
  INDEX RANGE SCAN EMP_IDX NON_UNIQUE 2 1
  
  2 row selected
  
  這樣,我們可以看到索引EMP_IDX被用于得到所有DEPTNO等于10的行,然后根據(jù)ROWID取得數(shù)據(jù),索引存儲(chǔ)了表中每行的ROWID,每當(dāng)在索引中找到一行,就會(huì)根據(jù)ROWID去查詢該行的其余部分。
假如是對(duì)一個(gè)很大的表的操作,這樣的搜索路徑較前一種(全表掃描)會(huì)對(duì)減少磁盤 I / O 操作有明顯的效果。但是,假如索引是“低選擇性的”,那么一個(gè)全表掃描可能會(huì)更有效。
  
  考慮以下的查詢及其執(zhí)行計(jì)劃:
  
  EXPLAIN PLAN
  
  SET STATEMENT_ID=‘QUERY3’
  
  FOR
  
  SELECT DEPTNO
  
  FROM EMP
  
  WHERE DEPTNO=10
  
  執(zhí)行路徑的計(jì)劃是:
  
  OPERATION OPTION Object_name Object_type ID Parent_ID
  
  INDEX RANGE_SCAN EMP_IDX NON_UNIQUE 1
  
  以上的執(zhí)行計(jì)劃表示不需在table中取得數(shù)據(jù),此查詢只須使用索引。
  
  EXPLAIN搜索路徑解釋
  任何SQL語句的執(zhí)行計(jì)劃都遵循一些優(yōu)化原則,這些原則在Oracle數(shù)據(jù)庫治理員手冊中有具體介紹。同時(shí),這些原則也被列在文本100040.163中。這些原則都試圖在從數(shù)據(jù)庫取出數(shù)據(jù)時(shí)找出一條最佳搜索路徑。一旦優(yōu)化器評(píng)估過查詢并確定了搜索路徑,優(yōu)化器就會(huì)創(chuàng)建一個(gè)執(zhí)行計(jì)劃樹。我們可以使用SQL*Plus查詢plan table從而看到執(zhí)行計(jì)劃樹:
  
  COLUMN plan FORMAT a70
  
  select lpad (‘ ‘, 3*level) operation (‘ options ’) ‘ object_name ‘ ‘ object_type
  
  from plan_table
  
  connect by PRior id=parent_id and statement_id=‘ & stmt_id’;
  
  例如下面這個(gè)查詢
  
  SELECT ENAME
  
  FROM EMP
  
  WHERE DEPTNO=10
  
  ORDER BY ENAME;
  
  使用以上SQL語句檢查plan table的結(jié)果是:
  
  SORT ( ORDER BY )
  
  TABLE ACCESS ( BY ROWID ) EMP
  
  INDEX ( RANGE SCAN ) EMP_IDX N0N_UNIQUE
  
  這個(gè)執(zhí)行計(jì)劃樹表示在EMP_IDX索引上執(zhí)行一個(gè)索引掃描,然后ENAME數(shù)據(jù)被按照ROWID從表中取了出來,最后這些數(shù)據(jù)被ORDER BY操作歸類。假如EMP表大的話,那么這個(gè)執(zhí)行計(jì)劃樹的最后一步可能花較長的時(shí)間。
  
  假設(shè)我們解釋如下查詢:
  
  select deptno, ename
  
  from emp
  
  where deptno between 1 and 30
  
  order by deptno;
  
  那么執(zhí)行樹為:
  
  TABLE ACCESS ( BY ROWID) EMP
  
  INDEX (RANGE SCAN) EMP_IDX NON_UNIQUE
  
  請注重,雖然在查詢時(shí)使用了order by,但在執(zhí)行樹中并未出現(xiàn)SORT (ORDER BY)。為什么呢?不使用SORT有二個(gè)原因:1) deptno列上已經(jīng)建立了index,已作過sort;2)deptno被定義為not null(如:DEPTNO NOT NULL NUMBER)。
  
  假設(shè)下面這個(gè)普通的連接查詢:
  
  SELECT *
  
  from emp. dept
  
  where emp.deptno=dept.deptno
  
  and sal >5000;
  
  執(zhí)行樹為:
  
  NESTED LOOPS ()
  
  TABLE ACCESS (FULL)DEPT
  
  TABLE ACCESS (BY ROWID)EMP
  
  INDEX (RANGE SCAN) EMP_IDX NON_UNIQUE
  
  NESTED LOOPS意味著在一個(gè)表(DEPT)上作了一個(gè)序列查詢,同時(shí)在EMP表上的索引EMP_IDX中,每一個(gè)DEPTNO均作查找。這個(gè)查詢被稱為一個(gè)驅(qū)動(dòng)表( driving table )。在這種情況下,驅(qū)動(dòng)表是DEPT。在這種類型的連接中,驅(qū)動(dòng)表是被列在后面的表。因?yàn)閮蓚€(gè)表有相同級(jí)別的搜索路徑 (都在deptno列上有非唯一的索引) ,既然至少有一個(gè)表上的所有記錄必須被檢索,那么在一個(gè)表上執(zhí)行全表掃描,同時(shí)在另一個(gè)表的索引上尋找符合條件的記錄是比較有效的。
  
  這種情況下,我們應(yīng)把具有最少列的表作為驅(qū)動(dòng)表放在from子句的最后,注重,在這種類型的連接中,from子句中表的先后次序決

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 军事| 栾城县| 清水县| 乌拉特后旗| 宜春市| 碌曲县| 海兴县| 禹城市| 年辖:市辖区| 宜阳县| 女性| 松溪县| 泸水县| 宜兴市| 赤壁市| 乐昌市| 温泉县| 平顺县| 通辽市| 喀喇沁旗| 浦北县| 平山县| 惠来县| 九江市| 宜兴市| 贵溪市| 滨州市| 炎陵县| 尼勒克县| 项城市| 宾川县| 苏尼特右旗| 文登市| 湖南省| 无为县| 浦城县| 丹巴县| 滁州市| 萨嘎县| 驻马店市| 华阴市|