• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Prayer

            在一般中尋求卓越
            posts - 1256, comments - 190, trackbacks - 0, articles - 0
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
            http://istl.inspur.com/showart.asp?id=27

            1、準備實驗環境

            我們創建了一個模擬tpch(數據庫工業標準測試)測試的數據庫,庫中一共有3張數據表,分別是:

            part      產品部件表

            supplier 供應商表

            partsupp 產品供應商關聯表

            其中part表中含有200000條數據,partsupp表中含有800000條數據,supplier表中含有10000條數據

            1) 我們為如上的3張表分別建立如下的索引:

            create index part_idx1 on tpcd.part(p_partkey,p_size);

            create index partsupp_idx1 on tpcd.partsupp(ps_partkey, ps_supplycost, ps_suppkey);

            create index supp_idx1 on tpcd.supplier(s_suppkey);

             

             

            2) 建立索引后,我們收集一下相關的統計信息,在db2cmd中執行如下的命令:

            runstats on table tpcd.part with distribution and detailed indexes all;

            runstats on table tpcd.partsupp with distribution and detailed indexes all;

            runstats on table tpcd.supplier with distribution and detailed indexes all;

             

             

            分別對PART, PARTSUPP, SUPPLIER運行以下命令,確保runstats已經成功執行:

            db2 “select card,npages,stats_time from syscat.tables where tabname=’PART’”

             

            CARD                 NPAGES               STATS_TIME

            -------------------- -------------------- -----------------------------------------------------------

             200000                 7616               2008-08-21-17.20.22.828000

             

             

            其中,CARD為該表的記錄數,NPAGES為該表所占有的存儲空間(頁數)STATS_TIME為收集統計信息的時間。

            2、發現問題

            1) 我們有如下的一個SQL語句:

             

            select

                count(*)

            from

                     tpcd.part,

                     tpcd.partsupp,

                     tpcd.supplier

            where

                     p_partkey = ps_partkey

                     and s_suppkey = ps_suppkey

                and p_size = 30

                     and ps_suppkey = 9988@

             

             

            目前,該SQL的運行速度不理想,我們希望通過調優提高這個SQL語句的執行效率。

            首先,我們為了記錄這條查詢語句執行的時間,運行如下SQL文件,記錄一個時間:

            文件名:lab.sql

            values current timestamp@

             

            select       

             count(*)

            from

             tpcd.part,       

             tpcd.partsupp,        

             tpcd.supplier

            where       

             p_partkey = ps_partkey 

             and s_suppkey = ps_suppkey       

             and p_size = 30     

             and ps_suppkey = 9988@

             

            values current timestamp@

             

             

            db2cmd中運行:

            db2 -td@ -vf lab.sql

             

             

            得到結果如下:

            1

            --------------------------

            2009-01-04-15.09.25.281000

            1 條記錄已選擇。

             

            select count(*) from tpcd.part, tpcd.partsupp, tpcd.supplier where p_partkey = ps_partkey and s_suppkey = ps_suppkey an p_size = 30 and ps_suppkey = 9988

            1

            -----------

            1

             1 條記錄已選擇。

             

            values current timestamp

            1

            --------------------------

            2009-01-04-15.09.33.359000

             

             1 條記錄已選擇。

             

             

            通過前后時間對比,我們發現這個SQL運行了大約6秒鐘(不同的機器性能可能有差異)

            3、分析問題

            1) 為了了解這個SQL的執行過程,我們開始分析它的執行計劃,在db2cmd中運行:

            db2expln -d tpcd -f lab.sql -t -z @ -g > lab-before.exp

             

            可以用文本編輯器打開lab-before.exp,下面,我們詳細解讀其中的執行計劃:如圖1所示

             

             

            分析:執行計劃是倒樹狀的結構,首先對part表、partsupp表和supplier表進行索引掃描,然后對partpartsupp表的索引掃描結果進行NLJOIN(嵌套循環連接),再將結果與supplier表的索引掃描結果進行HSJOINHASH連接),再進行排序,最后返回查詢結果。

            其中黃色標記部分,我們發現執行part表的索引掃描花費較大(1261.42個單位),且掃描結果(3810行)與我們的最終期望結果(1)差距較大,執行NLJOIN的花費(7443.881261.4215.1451=6167.31個單位),因此我們認為這里partpartsupp表建立的索引是影響查詢效率的因素。

            4、解決問題

            1) 在仔細分析的問題之后,我們嘗試來解決這個問題,我們規劃了一個新的索引方案,我們建立新的索引:

            drop index part_idx1;

            create index part_idx1 on tpcd.part(p_size,p_partkey);

            drop index partsupp_idx1;

            create index partsupp_idx1 on tpcd.partsupp(ps_suppkey,ps_partkey, ps_supplycost );

            drop index supp_idx1;

            create index supp_idx1 on tpcd.supplier(s_suppkey);

             

             

            我們改變了part表和partsupp表的索引順序

            2) 建立索引后,我們再收集一下相關的統計信息,在db2cmd中執行如下的命令:

            runstats on table tpcd.part with distribution and detailed indexes all;

            runstats on table tpcd.partsupp with distribution and detailed indexes all;

            runstats on table tpcd.supplier with distribution and detailed indexes all;

             

             

            3) 下面,我們再執行一下原來的SQL,在db2cmd中執行:

            db2 connect to tpcd

            db2 –td@ -vf lab.sql

            1

            --------------------------

            2009-01-04-16.02.45.078000

             1 條記錄已選擇。

             

            select count(*) from tpcd.part, tpcd.partsupp, tpcd.supplier where p_partkey = ps_partkey and s_suppkey = ps_suppkey an p_size = 30 and ps_suppkey = 9988

            1

            -----------

            1

             1 條記錄已選擇。

             

            values current timestamp

            1

            --------------------------

            2009-01-04-16.02.45.218000

             

             1 條記錄已選擇。

             

             

             

            通過前后時間對比,我們發現這次,這個SQL運行時間在1秒之內 (不同的機器性能可能有差異)

            4) 為了進一步分析這個SQL的執行過程,我們再分析一下SQL的執行計劃:

            db2cmd中運行:

            db2expln -d tpcd -f lab.sql -t -z @ -g > lab-after.exp

             

             

             

            可以用文本編輯器打開lab-after.exp,下面,我們詳細解讀這個執行計劃,如圖2所示

             

            從執行的總花費(84.817)上我們可以明顯的看到優化后的效果。

            5、解決方案分析

            我們來看實驗Sql語句的謂詞部分:

            p_partkey = ps_partkey

               and s_suppkey = ps_suppkey

                 and p_size = 30

                     and ps_suppkey = 9988@

             

            DB2sql優化器在執行查詢sql語句,根據謂詞進行表連接查詢,并不依賴于where條件中謂詞的順序,而是根據所建索引來進行先后順序的連接。

            我們再來看優化前的索引:

            create index part_idx1 on tpcd.part(p_partkey,p_size);

            create index partsupp_idx1 on tpcd.partsupp(ps_partkey, ps_supplycost, ps_suppkey);

            create index supp_idx1 on tpcd.supplier(s_suppkey);

             

            1)我們目標是盡量增大第一次或前幾次join的數據量縮小幅度,所以首先要進行小表的索引掃描和連接。而這里,從業務角度來說,把業務主鍵放到索引的第一個位置是有意義的,但是對于優化器來說,這毫無意義。優化器會根據索引優化器會首先選擇謂詞:p_partkey = ps_partkey partpartsupp進行NLJOIN,而這兩個表是數據量相對大的表。

            2NLJOIN中外表只掃描一次,內表掃描N次,所以內表要盡量的小一些。而這里的內表partsupp800000條數據。

            我們期望優化器做如下處理:

            1)優化器首先根據謂詞p_size = 30 ps_suppkey = 9988@進行索引掃描,縮小數據范圍。

            2)優化器根據謂詞s_suppkey = ps_suppkeysupplierpartsupp進行表的NLJOIN。內表(partsupp)是數據量較小的一個表

            所以,我們要將p_sizeps_suppkey的索引提前,建立如下索引

            create index part_idx1 on tpcd.part(p_size,p_partkey);

            create index partsupp_idx1 on tpcd.partsupp(ps_suppkey,ps_partkey, ps_supplycost );

            create index supp_idx1 on tpcd.supplier(s_suppkey);

             

             

            6、總結

            使用db2expln解釋工具,能夠得到DB2 Sql優化器的詳細Sql執行計劃,通過其中的花費我們可以結合sql語句及表、索引、連接的結構進行分析,發現并定位問題,然后對sql進行改進,達到優化的目標。

            91精品国产综合久久四虎久久无码一级| 久久Av无码精品人妻系列| 国产精品99久久不卡| 久久精品国产亚洲Aⅴ香蕉| 久久精品视频一| 精品一区二区久久久久久久网站| 久久精品国产精品亚洲艾草网美妙 | 久久久久久精品成人免费图片| 狠狠色丁香婷婷久久综合五月| 国产精品女同久久久久电影院| 欧美与黑人午夜性猛交久久久| 无码日韩人妻精品久久蜜桃| 青青青青久久精品国产h| 日日狠狠久久偷偷色综合免费| 国产一区二区精品久久岳| 久久亚洲熟女cc98cm| 久久婷婷国产麻豆91天堂| 伊人久久综合无码成人网| 久久久精品国产Sm最大网站| 精品久久久久久久无码| 久久亚洲国产精品成人AV秋霞| 亚洲另类欧美综合久久图片区| 国产精品热久久无码av| 久久国产精品77777| 亚洲精品无码久久一线| 国产精品热久久毛片| 欧美日韩中文字幕久久伊人| 精品无码久久久久国产| 中文字幕久久波多野结衣av| 国产精品成人久久久| 香港aa三级久久三级老师2021国产三级精品三级在 | 亚洲色欲久久久综合网东京热| 开心久久婷婷综合中文字幕| 精品久久久久久综合日本| 日本人妻丰满熟妇久久久久久| 久久久久青草线蕉综合超碰| 亚洲国产成人久久综合碰| 国产精品美女久久久久av爽| 狠狠狠色丁香婷婷综合久久五月| 99精品伊人久久久大香线蕉| 国产99精品久久|