佳木斯湛栽影视文化发展公司

主頁 > 知識庫 > Oracle SQL tuning 數(shù)據(jù)庫優(yōu)化步驟分享(圖文教程)

Oracle SQL tuning 數(shù)據(jù)庫優(yōu)化步驟分享(圖文教程)

熱門標(biāo)簽:Linux服務(wù)器 百度競價(jià)排名 鐵路電話系統(tǒng) 網(wǎng)站排名優(yōu)化 服務(wù)外包 AI電銷 地方門戶網(wǎng)站 呼叫中心市場需求

SQL Turning 是Quest公司出品的Quest Central軟件中的一個(gè)工具。Quest Central是一款集成化、圖形化、跨平臺的數(shù)據(jù)庫管理解決方案,可以同時(shí)管理 Oracle、DB2 和 SQL server 數(shù)據(jù)庫。

一、SQL Tuning for SQL Server簡介

SQL語句的優(yōu)化對發(fā)揮數(shù)據(jù)庫的最佳性能非常關(guān)鍵。然而不幸的是,應(yīng)用優(yōu)化通常由于時(shí)間和資源的因素而被忽略。SQL Tuning (SQL優(yōu)化)模塊可以對比和評測特定應(yīng)用中SQL語句的運(yùn)行性能,提出智能化的優(yōu)化建議,幫助用戶改善應(yīng)用的響應(yīng)時(shí)間。SQL優(yōu)化模塊具有非介入式SQL采集、自動優(yōu)化和專家建議等功能,全面改善SQL優(yōu)化工作。

二、SQL Tuning for SQL Server的使用

1、打開Quest Database Management Solutions彈出窗口如圖1所示

圖1  

2、在紅色標(biāo)記處打開SQL Tuning 優(yōu)化SQL    

  (1)建立連接。

在Quest Central主界面上的“Database”樹上選擇“SQL Server”,然后在下方出現(xiàn)的“Tools”框中選擇“SQL Tuning”選項(xiàng),打開“Lanch SQL Tuning for SQL Server Connections”對話框(圖2、圖3)。我們在這里建立數(shù)據(jù)庫服務(wù)器的連接,以后的分析工作都會在它上面完成。 

圖2 “建立連接”對話框 

圖3

     雙擊“New Connection”圖標(biāo),在彈出窗口中輸入數(shù)據(jù)庫的信息,單擊“OK”,然后單擊“Connect”即可。

   (2)分析原始SQL語句 ,在單擊“Connect”后將彈出一個(gè)新窗口,如圖4 

圖4

在打開窗口的“Oriangal SQL”文本框內(nèi)輸入需要分析的原始SQL語句,紅色標(biāo)記處選擇對應(yīng)的數(shù)據(jù)庫名,SQL語句代碼如下:

圖5 分析原始SQL語句

原始SQL語句

然后點(diǎn)擊工具欄上的“Execute”按鈕,執(zhí)行原始的SQL語句,SQL Tuning會自動分析SQL的執(zhí)行計(jì)劃,并把分析結(jié)果顯示到界面上(圖5)。

(3)優(yōu)化SQL。

現(xiàn)在我們點(diǎn)擊工具欄上的“Optimize Statement”按鈕,讓SQL Tuning開始優(yōu)化SQL,完成后,可以看到SQL Tuning產(chǎn)生了19條與原始SQL等價(jià)的優(yōu)化方案(圖6)。 

圖6 SQL優(yōu)化方案

(4)獲得最優(yōu)SQL。

接下來,我們來執(zhí)行上面產(chǎn)生的優(yōu)化方案,以選出性能最佳的等效SQL語句。在列表中選擇需要執(zhí)行的優(yōu)化方案(默認(rèn)已全部選中),然后點(diǎn)擊工具欄上的“Execute”按鈕旁邊的下拉菜單,選擇“Execute Selected”。等到所有SQL運(yùn)行完成后,點(diǎn)擊界面左方的“Tuning Resolution”按鈕,
可以看到最優(yōu)的SQL已經(jīng)出來啦,運(yùn)行時(shí)間竟然可以提高21%?。▓D7)

圖7 “Tuning Resolution”界面 

最優(yōu)的SQL語句如下:

5)學(xué)習(xí)書寫專家級的SQL語句 。

優(yōu)化后的SQL語句

SELECT dbo.Person_BasicInfo.*, 
       dbo.Graduater_GraduaterRegist.RegistNO AS RegistNO, 
       dbo.Graduater_GraduaterRegist.RegistTime AS BaoDaoTime, 
       dbo.Graduater_GraduaterRegist.RegistMan AS RegistMan, 
       dbo.Graduater_Business.ComeFrom AS ComeFrom, 
       dbo.Graduater_Business.Code AS Code, 
       dbo.Graduater_Business.Status AS Status, 
       dbo.Graduater_Business.ApproveResult AS ApproveResult, 
       dbo.Graduater_Business.NewCorp AS NewCorp, 
       dbo.Graduater_Business.CommendNumber AS CommendNumber, 
       dbo.Graduater_Business.EmployStatus AS EmployStatus, 
       dbo.Graduater_Business.NewCommendTime AS NewCommendTime, 
       dbo.Graduater_Business.GetSource AS GetSource, 
       dbo.Graduater_Business.EmployTime AS EmployTime, 
       dbo.Graduater_Business.Job AS Job, 
       dbo.Graduater_Business.FillMan AS FillMan, 
       dbo.Graduater_Business.FillTime AS FillTime, 
       dbo.Graduater_Business.IsCommendOK AS IsCommendOK, 
       dbo.Graduater_Business.ApproveUser AS ApproveUser, 
       dbo.Graduater_Business.ApproveTime AS ApproveTime, 
       dbo.Graduater_Business.RegistTime AS RegistTime, 
       dbo.Graduater_Business.EmployCorp AS EmployCorp, 
       dbo.Graduater_Business.JobRemark AS JobRemark, 
       CASE WHEN dbo.Graduater_Business.ComeFrom = 'WS' THEN '網(wǎng)上登記' 
            WHEN dbo.Graduater_Business.ComeFrom = 'HP' THEN '華普大廈' 
            WHEN dbo.Graduater_Business.ComeFrom = 'JD' THEN '精典大廈' 
            WHEN dbo.Graduater_Business.ComeFrom = 'MC' THEN '賽馬場' 
            WHEN ComeFrom = 'ZX' THEN '高指中心' END AS ComeFromName, 
       dbo.Person_Contact.Address AS Address, 
       dbo.Person_Contact.Zip AS Zip, 
       dbo.Person_Contact.Telephone AS Telephone, 
       dbo.Person_Contact.Mobile AS Mobile, 
       dbo.Person_Contact.Email AS Email, 
       dbo.Person_Contact.IM AS IM, 
       dbo.Person_Skill.ForeignLanguage AS ForeignLanguage, 
       dbo.Person_Skill.ForeignLanguageLevel AS ForeignLanguageLevel, 
       dbo.Person_Skill.CantoneseLevel AS CantoneseLevel, 
       dbo.Person_Skill.MandarinLevel AS MandarinLevel, 
       dbo.Person_Skill.Language AS Language, 
       dbo.Person_Skill.TechnicalTitle AS TechnicalTitle, 
       dbo.Person_Skill.ComputerLevel AS ComputerLevel, 
       dbo.Person_EmployPurpose.JobType AS JobType, 
       dbo.Person_EmployPurpose.Vocation AS Vocation, 
       dbo.Person_EmployPurpose.JobPlace AS JobPlace, 
       dbo.Person_EmployPurpose.Salary AS Salary, 
       dbo.Person_EmployPurpose.OnJobDate AS OnJobDate, 
       dbo.Person_EmployPurpose.CorpType AS CorpType, 
       dbo.Person_EmployPurpose.Job AS RequireJob, 
       YEAR(GETDATE()) - YEAR(dbo.Person_BasicInfo.Birthday) AS Age, 
       dbo.Graduater_Business.EmployType AS EmployType, 
       dbo.Graduater_Business.EmployTypeCode AS EmployTypeCode, 
       dbo.Graduater_Business.EmployCorpType AS EmployCorpType, 
       CASE WHEN dbo.Graduater_Business.PrintStatus = '已打印' THEN '已打印' 
            ELSE '未打印' END AS PrintStatus, 
       dbo.Graduater_Business.PrintTime AS PrintTime, 
       CASE WHEN dbo.Graduater_Business.EmployStatus = '是' THEN '已就業(yè)' 
            ELSE '未就業(yè)' END AS EmployStatusView 
  FROM dbo.Person_BasicInfo 
       INNER JOIN dbo.Graduater_Business 
          ON dbo.Person_BasicInfo.PersonID = dbo.Graduater_Business.PersonID 
       LEFT OUTER JOIN dbo.Graduater_GraduaterRegist 
         ON dbo.Graduater_Business.GradBusinessID = dbo.Graduater_GraduaterRegist.GraduaterGUID 
       INNER JOIN dbo.Person_Contact 
          ON dbo.Person_BasicInfo.PersonID = dbo.Person_Contact.PersonID 
       INNER JOIN dbo.Person_Skill 
          ON dbo.Person_BasicInfo.PersonID = dbo.Person_Skill.PersonID 
       INNER JOIN dbo.Person_EmployPurpose 
          ON dbo.Person_BasicInfo.PersonID = dbo.Person_EmployPurpose.PersonID 
OPTION (FORCE ORDER)

 (

    通過上面的步驟,我們已經(jīng)可以實(shí)現(xiàn)自動優(yōu)化SQL語句,但更重要的是,我們還可以學(xué)習(xí)如何書寫這樣高性能的SQL語句。點(diǎn)擊界面左方的“Compare Scenarios”按鈕,我們可以比較優(yōu)化方案和原始SQL中的任意2條SQL語句,SQL Tuning會將它們之間的不同之處以不同顏色表示出來,
還可以在下方的“執(zhí)行計(jì)劃”中,通過比較兩條SQL語句的執(zhí)行計(jì)劃的不同,來了解其中的差異(圖8)。 

圖8 “Compare Scenarios”界面

Oracle SQL tuning的目標(biāo)
    Oracle SQL tuning是一個(gè)復(fù)雜的課題。Oracle Tuning: The Definitive Reference 這整本書描述了關(guān)于SQL tuning的細(xì)節(jié)。盡管如此,
    為了提高系統(tǒng)系能,Oracle DBA應(yīng)當(dāng)遵從下面一些總的指導(dǎo)原則。

1、SQL tuning 目標(biāo)
   是以最小的數(shù)據(jù)庫訪問次數(shù)提取更多地?cái)?shù)據(jù)行來生成最佳的執(zhí)行計(jì)劃(盡可能最小化物理讀(PIO)與邏輯讀(LIO)。

    指導(dǎo)原則
        移除不必要的大型全表掃描
            大型表的全表掃描將產(chǎn)生龐大的系統(tǒng)I/O且使得整個(gè)數(shù)據(jù)庫性能下降。優(yōu)化專家首先會評估當(dāng)前SQL查詢所返回的行數(shù)。最常見的辦
        法是為走全表掃描的大表增加索引。B樹索引,位圖索引,以及基于函數(shù)的索引等能夠避免全表掃描。有時(shí)候,對一些不必要的全表掃
        描通過添加提示的方法來避免全表掃描。

        緩存小表全表掃描
            有時(shí)候全表掃描是最快的訪問方式,管理員應(yīng)當(dāng)確保專用的數(shù)據(jù)緩沖區(qū)(keep buffer cache,nk buffer cache)對這些表可用。在
            Oracle 8 以后小表可以被強(qiáng)制緩存到 keep 池。

        使用最佳索引
            Oracle 訪問對象有時(shí)候會有一個(gè)以上的索引選擇。因此應(yīng)當(dāng)檢查當(dāng)前查詢對象上的每一個(gè)索引以確保Oracle使用了最佳索引。

        物化聚合運(yùn)算以靜態(tài)化表統(tǒng)計(jì)
            Oracle 10g的特性之一SQL Access advisor 會給出索引建議以及物化視圖的建議。物化視圖可以預(yù)連接表和預(yù)摘要表數(shù)據(jù)。(譯者
            按,即Oracle可以根據(jù)特定的更新方式來提前更新物化視圖中的數(shù)據(jù),而在查詢時(shí)僅僅查詢物化視圖即可得到最終所需的統(tǒng)計(jì)數(shù)據(jù)
            結(jié)果。物化視圖實(shí)際上是一張實(shí)體表)

    以上這些概括了SQL tuning的目標(biāo)。然而看是簡單,調(diào)整起來并不容易,因?yàn)檫@需要對Oracle SQL內(nèi)部有一個(gè)徹底的了解。接下來讓我們從
    整體上來認(rèn)識 Oracle SQL 優(yōu)化。

2、Oracle SQL 優(yōu)化器
    Oracle DBA首先要查看的是當(dāng)前數(shù)據(jù)庫缺省的優(yōu)化器模式。Oracle初始化參數(shù)提供很多基于成本優(yōu)化的優(yōu)化器模式以及之前廢棄的基于規(guī)則
    的優(yōu)化器模式(或hint)供選擇?;诔杀镜膬?yōu)化器主要依賴于表對象使用analyze命令收集的統(tǒng)計(jì)信息。Oracle根據(jù)表上的統(tǒng)計(jì)信息得以決定
    并為當(dāng)前的SQL生成最高效的執(zhí)行計(jì)劃。需要注意的是在一些場合基于成本優(yōu)化器可能會做出不正確的決定。基于成本的優(yōu)化器在不斷的改進(jìn),
    但是依然有很多場合使用基于規(guī)則的優(yōu)化器能夠使得查詢更高效。

    在Oracle 10g之前,Oracle 缺省的優(yōu)化器模式是CHOOSE模式。在該模式下,如果表對象上缺乏統(tǒng)計(jì)信息則此時(shí)Oracle使用基于規(guī)則的優(yōu)化
    器;如果統(tǒng)計(jì)信息存在則使用基于成本的優(yōu)化器。使用CHOOSE模式存在的隱患即是對一些復(fù)雜得查詢有些對象上有統(tǒng)計(jì)信息,而另一些對象
    缺乏統(tǒng)計(jì)信息。

    在Oracle 10g開始,缺省的優(yōu)化器模式是 ALL_ROWS,這有助于全表掃描優(yōu)于索引掃描。ALL_ROWS優(yōu)化器模式被設(shè)計(jì)成最小化計(jì)算資源且有
    助于全表掃描。索引掃描(first_rows_n)增加了額外的I/O開銷。但是他們能更快地返回?cái)?shù)據(jù)。

因此,大多數(shù)OLTP系統(tǒng)選擇first_rows,first_rows_100 或者 first_rows_10以使得Oracle使用索引掃描來減少讀塊數(shù)量。

    注意:從Oracle 9i R2開始,Oracle 性能調(diào)整指導(dǎo)指出了first_rows 優(yōu)化器模式已經(jīng)被廢棄,且使用first_rows_n代替

    當(dāng)僅有一些表包含CBO統(tǒng)計(jì)信息,而另一些缺乏統(tǒng)計(jì)信息時(shí),Oracle使用基于成本的優(yōu)化模式來預(yù)估其他表在運(yùn)行時(shí)的統(tǒng)計(jì)信息(即動態(tài)采樣
    ),這在很大程度上影響單個(gè)查詢性能下降。

    總之,Oracle 數(shù)據(jù)庫管理員應(yīng)當(dāng)總是將嘗試改變優(yōu)化器模式作為SQL tuning的第一步。Oracle SQL tuning的首要原則是避免可怕的全表掃
    描。一個(gè)特性之一是一個(gè)非高效的SQL語句為提高查詢性能使用所有的索引此仍然為一個(gè)失敗的SQL語句。

    當(dāng)然,有些時(shí)候使用全表掃描是合適的,尤其是在做聚合操作象sum,avg等操作,因?yàn)闉榱双@得結(jié)果,表上的絕大部分?jǐn)?shù)據(jù)行必須被讀入到
    緩存。SQL tuning 高手應(yīng)當(dāng)合理的評估每一個(gè)全表掃描并要核實(shí)使用索引能否提高性能。

    在大多數(shù)Oracle 系統(tǒng),SQL語句檢索的僅僅是表上數(shù)據(jù)一個(gè)子集。Oracle 優(yōu)化器會檢查使用索引是否會導(dǎo)致更多的I/O。然而,如果構(gòu)建了
    一個(gè)低效的查詢,基于成本的優(yōu)化器難以選擇最佳的數(shù)據(jù)訪問路徑,轉(zhuǎn)而傾向于使用全表掃描。故Oracle數(shù)據(jù)庫管理員應(yīng)當(dāng)總是審查那些走
    全表掃描的SQL語句。

    更多有關(guān)全表掃描的問題,以及選擇正確的優(yōu)化模式請 :"Oracle Tuning: The Definitive Reference"

三、SQL 調(diào)整戰(zhàn)略步驟
    很多人問SQL tuning從哪里著手。首先應(yīng)當(dāng)是從Library cache去根據(jù)他們的活動狀況捕獲SQL語句。

1、尋找影響較大的SQL語句
    我們可以根據(jù)SQL語句執(zhí)行次數(shù)的多少進(jìn)行排序來獲得執(zhí)行次數(shù)較多的SQL語句。在v$sqlarea視圖中executions 列以及表stats$sql_summary
    或 dba_hist_sql_summary 能夠去定位當(dāng)前最頻繁使用的SQL語句。注:也可以按照下列方式列出SQL語句。
        Rows processed
            處理的行數(shù)越多,則相應(yīng)會有很高的I/O,也有可能耗用大量的臨時(shí)表空間

        Buffer gets
            Buffer gets過高可能表明資源被過度集中化查詢,存在熱塊現(xiàn)象

        Disk reads
            高的磁盤讀將引起過度的I/O

        Memory KB
            內(nèi)存的分配大小可以鑒別該SQL語句是否在內(nèi)存中使用了大量的表連接

        CPU secs
            CPU的開銷表明哪些SQL語句耗用了大量的CPU資源

        Sorts
            排序越多,則SQL性能越差,而且會占用大量的臨時(shí)表空間

        Executions
            執(zhí)行次數(shù)表明了當(dāng)前SQL語句的頻繁度,應(yīng)當(dāng)被首先考慮調(diào)整,因?yàn)檫@些語句影響了數(shù)據(jù)庫的整體性能

2、決定SQL的執(zhí)行計(jì)劃
    每一個(gè)SQL語句都可以根據(jù)SQL_ID來獲得其執(zhí)行計(jì)劃。有大量的第三方工具來獲得SQL語句的執(zhí)行計(jì)劃。而獲得執(zhí)行最常用的方式是使用Oracle
    自帶的explain plan程序。通過使用該程序,Oracle DBA能夠在不執(zhí)行SQL 語句的情形下解析并顯示該SQL語句的執(zhí)行計(jì)劃。

    查看SQL執(zhí)行計(jì)劃的輸出,必須首先創(chuàng)建一個(gè)plan table. Oracle提供一個(gè)utlxplan.sql腳本來創(chuàng)建該表。執(zhí)行該腳本并且為該表創(chuàng)建一個(gè)
    公共同義詞。

    sqlplus > @utlxplan
    Table created.

    sqlplus > create public synonym plan_table for sys.plan_table;
    Synonym created.

    大多數(shù)關(guān)系數(shù)據(jù)庫使用解釋程序?qū)QL語句作為輸入,然后運(yùn)行SQL優(yōu)化器,輸出訪問的路徑信息到一個(gè)plan_table。以便我們能夠查看及調(diào)
    整其訪問方式。下面的是一個(gè)復(fù)雜的SQL查詢。

    EXPLAIN PLAN SET STATEMENT_ID = 'test1' FOR
    SET STATEMENT_ID = 'RUN1'
    INTO plan_table
    FOR
    SELECT   'T'||plansnet.terr_code, 'P'||detplan.pac1
    || detplan.pac2 || detplan.pac3, 'P1', sum(plansnet.ytd_d_ly_tm),
     sum(plansnet.ytd_d_ty_tm),
     sum(plansnet.jan_d_ly),
     sum(plansnet.jan_d_ty),
    FROM plansnet, detplan
    WHERE
        plansnet.mgc = detplan.mktgpm
    AND
        detplan.pac1 in ('N33','192','195','201','BAI',
        'P51','Q27','180','181','183','184','186','188',
        '198','204','207','209','211')
    GROUP BY 'T'||plansnet.terr_code, 'P'||detplan.pac1 || detplan.pac2 || detplan.pac3;

    這個(gè)語法使用管道輸入到SQL優(yōu)化器,解析SQL,存儲執(zhí)行計(jì)劃信息到表plan_table,且RUN1作為鑒別當(dāng)前SQL語句的標(biāo)識符。注意,該查詢
    并沒有執(zhí)行,它僅僅是創(chuàng)建了一個(gè)內(nèi)部訪問信息且輸出到plan_table。plan 表包含下列字段。

        operation
            表明當(dāng)前語句完成的操作,通常包括table access, table merge, sort, or index operation

        options
            補(bǔ)充說明operation,像full table, range table, join

        object_name
            查詢組件的名字

        Process ID
            查詢組件的ID號

        Parent_ID
            查詢組建的父ID,注意,有些查詢會有一個(gè)相同的父ID

    現(xiàn)在plan_table已經(jīng)被填充,可以使用下面的查詢來查看當(dāng)前SQL語句的執(zhí)行計(jì)劃。

        plan.sql - displays contents of the explain plan table
        SET PAGES 9999;
        SELECT  lpad(' ',2*(level-1))||operation operation,
                options,
                object_name,
                position
        FROM plan_table
        START WITH id=0
        AND
        statement_id = 'RUN1'
        CONNECT BY prior id = parent_id
        AND
        statement_id = 'RUN1';

    下面給出了當(dāng)前語句執(zhí)行計(jì)劃信息以及各個(gè)部分的執(zhí)行順序。
    SQL> @list_explain_plan

    OPERATION
    -------------------------------------------------------------------------------------
    OPTIONS                           OBJECT_NAME                    POSITION
    ------------------------------ -------------------------------------------------------
    SELECT STATEMENT
    SORT
    GROUP BY                                                      1
           CONCATENATION                                   1
    NESTED LOOPS                                    1
    TABLE ACCESS FULL         PLANSNET                   1
    TABLE ACCESS BY ROWID     DETPLAN                    2
              INDEX RANGE SCAN       DETPLAN_INDEX5             1
    NESTED LOOPS

    從上面的執(zhí)行計(jì)劃中得知當(dāng)前的SQL語句存在表掃描現(xiàn)象。去調(diào)整該SQL語句,我們應(yīng)當(dāng)尋找表where 子句中為planset上的列。在這里我們
    看到了在where子句存在一個(gè)且屬于表planset上的列mgc被用作連接條件。這說明一個(gè)基于表planset.mgs列上的索引是必要的。

    plan table并不能展現(xiàn)整個(gè)SQL語句的細(xì)節(jié),但對于獲得數(shù)據(jù)訪問路徑是非常有用的。SQL優(yōu)化器知道每一個(gè)表的行數(shù)(基數(shù))以及一些索引字
    段的狀況。但并不了解數(shù)據(jù)的分布象如一個(gè)組件期待返回的行數(shù)。

3、調(diào)整SQL語句
    對于那些存在可優(yōu)化的子執(zhí)行計(jì)劃,SQL應(yīng)當(dāng)按照下面的方式進(jìn)行調(diào)整。

    通過添加提示來修改SQL的執(zhí)行計(jì)劃

    使用全局臨時(shí)表來重寫SQL

    使用PL/SQL來重寫SQL。對于一些特定查詢該方法能夠有20倍左右的提升。將這些SQL封裝到包含存儲過程的包中去完成查詢。

    使用提示來調(diào)整SQL

    大多數(shù)SQL tuning工具中使用較多的莫過于使用提示。一個(gè)提示添加的SQL語句后使得SQL查詢的按指定路徑訪問。

    Troubleshooting tip! 
    為便于測試,我們能夠隨時(shí)使用alter session命令來修改一個(gè)優(yōu)化參數(shù)的值來觀察調(diào)整前后的結(jié)果比較。使用新的 opt_param 提示能獲得
    同樣的效果。

    select /*+ opt_param('optimizer_mode','first_rows_10') */ col1, col2 . . .
    select /*+ opt_param('optimizer_index_cost_adj',20) */ col1, col2 . .

    Oracle 發(fā)布了大量的SQL提示,而且提示隨著Oracle版本的不同不斷的增強(qiáng)和復(fù)雜化。

    注意:提示通常用于調(diào)試SQL,最佳的辦法是調(diào)整優(yōu)化器的統(tǒng)計(jì)信息使的CBO模式自動獲取最佳執(zhí)行路徑,等同于使用提示的功能。
    我們來看看提高性能最常用的提示

        Mode hints:  first_rows_10, first_rows_100
        Oracle leading and ordered hints  Also see how to tune table join order with histograms

        Dynamic sampling: dynamic_sampling

        Oracle SQL undocumented tuning hints - Guru's only
        The cardinality hint    

    表連接順序
        當(dāng)表連接的順序可優(yōu)化時(shí),我們可以使用 ORDERED提示來強(qiáng)制表按照from子句中出現(xiàn)的先后順序來進(jìn)行連接

    first_rows_n提示
        Oracle 有兩個(gè)基于成本優(yōu)化的提示,一個(gè)是first_rows_n,一個(gè)是all_rows。first_rows模式將盡可能在一查詢到數(shù)據(jù)時(shí)就返回個(gè)客
        戶端。而 all_rows 模式則為優(yōu)化資源而設(shè)計(jì),需要等到所有結(jié)果計(jì)算執(zhí)行完畢才返回?cái)?shù)據(jù)給客戶端。

        SELECT /*+ first_rows */

4、案例
    同一個(gè)SQL語句有不同的寫法。即簡單的SQL查詢能夠以不同的方式來產(chǎn)生相同的結(jié)果集,但其執(zhí)行效率和訪問方式則千差萬別。

    下面的例子中的SQL語句使用了3種不同的寫法來返回相同的結(jié)果

    A standard join:  -->標(biāo)準(zhǔn)連接

    SELECT *
    FROM STUDENT, REGISTRATION
    WHERE
        STUDENT.student_id = REGISTRATION.student_id
    AND
        REGISTRATION.grade = 'A';

    A nested query:  -->嵌套查詢

    SELECT *
    FROM STUDENT
    WHERE
        student_id =
        (SELECT student_id
            FROM REGISTRATION
            WHERE
           grade = 'A'
        );

    A correlated subquery:  -->相關(guān)子查詢

    SELECT *
    FROM STUDENT
    WHERE
        0
        (SELECT count(*)
            FROM REGISTRATION
            WHERE
            grade = 'A'
            AND
            student_id = STUDENT.student_id
        );

    我們應(yīng)該根據(jù)基本的SQL原則來優(yōu)化當(dāng)前的SQL語句。

5、書寫高效SQL語句的技巧
        下面給出一些編寫高效SQL語句的總的指導(dǎo)原則,而不論Oracle優(yōu)化器選擇何種優(yōu)化模式。這些看是簡單的方式但是按照他們
    去做將收到事半功倍的效果(已經(jīng)在實(shí)踐中被證實(shí))。

    a.使用臨時(shí)表重寫復(fù)雜的子查詢
        Oracle 使用全局臨時(shí)表以及WITH操作符去解決那些復(fù)雜的SQL子查詢。尤其是那些where子句中的子查詢,SELECT 字句標(biāo)量子查詢,
        FROM 子句的內(nèi)聯(lián)視圖。使用臨時(shí)表實(shí)現(xiàn)SQL tuning(以及使用WITH的物化視圖)能夠使得性能得以驚人的提升。

    b.使用MINUS 代替EXIST子查詢
        使用MINUS操作代替NOT IN 或NOT EXISTS將產(chǎn)生更高效的執(zhí)行計(jì)劃(譯者按:此需要測試)。

    c.使用SQL分析函數(shù)
        Oracle 分析函數(shù)能夠一次提取數(shù)據(jù)來做多維聚合運(yùn)算(象ROLLUP,CUBE)以提高性能。

    d.重寫NOT EXISTS和查詢作為外部連接NOT EXISTS 子查詢
        在一些案例中的NOT 查詢(where 中一個(gè)列被定義為NULL值),能夠?qū)⑵涓膶戇@個(gè)非相關(guān)子查詢到IS NULL 的外部鏈接。如下例:
        select book_key from book
        where
        book_key NOT IN (select book_key from sales);

        下面我們在where子句中使用了外部連接來替代原來的not exits,得到一個(gè)更高效的執(zhí)行計(jì)劃。

        select b.book_key from book b, sales s
        where
           b.book_key = s.book_key(+)
        and
           s.book_key IS NULL;

    e.索引NULL值列
        如果你的SQL語句頻繁使用到NULL值,應(yīng)當(dāng)考慮基于NULL值創(chuàng)建索引。為使該查詢最優(yōu)化,可以創(chuàng)建一個(gè)使用基于NULL值索引函數(shù)。
        (譯者按,如 create index i_tb_col on tab(nvl(col,null)); create index i_tb_col on tab(col,0);)

    f.避免基于索引的運(yùn)算
        不要基于索引列做任何運(yùn)算,除非你創(chuàng)建了一個(gè)相應(yīng)的索引函數(shù)?;蛘咧卦O(shè)設(shè)計(jì)列以使得where子句列上的謂詞不需要轉(zhuǎn)換。
        -->下面都是低效的SQL寫法
        where salary*5            > :myvalue   
        where substr(ssn,7,4)     = "1234"
        where to_char(mydate,mon) = "january"

    g.避免使用NOT IN 和HAVING 
        在合適的時(shí)候使用not exists子查詢更高效。

    h.避免使用LIKE謂詞
        在合適地時(shí)候,如果能夠使用 = 運(yùn)算應(yīng)盡可能避免LIKE操作。

    i.避免數(shù)據(jù)類型轉(zhuǎn)換
        如果一個(gè)where 子句列是數(shù)字型,則不要使用引號。而對一個(gè)字符索引列,總是使用引號。下面是數(shù)據(jù)類型混用的情形。
        where cust_nbr = "123"
        where substr(ssn,7,4) = 1234

    j.使用decode與case
        使用decode 與case 函數(shù)能夠最小化查詢表的次數(shù)。

    k.不要害怕全表掃描
        并不是所有的OLTP系統(tǒng)在使用索引時(shí)是最優(yōu)化的。如果你的查詢返回了表中的絕大部分?jǐn)?shù)據(jù),則全表掃描性能優(yōu)于索引掃描。這取決于
        一些因素包括你的配置(db_file_multiblock_read_count, db_block_size),并行查詢,以及表塊和索引塊在buffer cache中的數(shù)量。

    l.使用別名
        在參照列的地方總是使用表別名。
    --> Author : Robinson Cheng
    --> Blog   : http://blog.csdn.net/robinson_0612

您可能感興趣的文章:
  • Oracle 表三種連接方式使用介紹(sql優(yōu)化)
  • oracle數(shù)據(jù)庫sql的優(yōu)化總結(jié)
  • oracle下一條SQL語句的優(yōu)化過程(比較詳細(xì))
  • Oracle SQL性能優(yōu)化系列學(xué)習(xí)一
  • Oracle SQL性能優(yōu)化系列學(xué)習(xí)二
  • Oracle SQL性能優(yōu)化系列學(xué)習(xí)三
  • ORACLE SQL語句優(yōu)化技術(shù)要點(diǎn)解析

標(biāo)簽:湘潭 湖南 銅川 仙桃 衡水 崇左 蘭州 黃山

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Oracle SQL tuning 數(shù)據(jù)庫優(yōu)化步驟分享(圖文教程)》,本文關(guān)鍵詞  ;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 收縮
    • 微信客服
    • 微信二維碼
    • 電話咨詢

    • 400-1100-266
    徐汇区| 军事| 齐齐哈尔市| 双柏县| 万州区| 革吉县| 日喀则市| 将乐县| 旬邑县| 汨罗市| 巢湖市| 滦南县| 田东县| 凌源市| 禹州市| 外汇| 新平| 砀山县| 邹城市| 射洪县| 兰坪| 嘉荫县| 桦南县| 靖宇县| 康平县| 克什克腾旗| 郓城县| 桐乡市| 建阳市| 临潭县| 永川市| 正镶白旗| 宽甸| 双牌县| 万州区| 景谷| 芮城县| 遂昌县| 政和县| 嘉鱼县| 马龙县|