隨筆 - 154  文章 - 60  trackbacks - 0
          <2008年2月>
          272829303112
          3456789
          10111213141516
          17181920212223
          2425262728291
          2345678

          聲明:

          該blog是為了收集資料,認識朋友,學習、提高技術,所以本blog的內容除非聲明,否則一律為轉載??!

          感謝那些公開自己技術成果的高人們!??!

          支持開源,尊重他人的勞動??!

          常用鏈接

          留言簿(3)

          隨筆分類(148)

          隨筆檔案(143)

          收藏夾(2)

          其他

          學習(技術)

          觀察思考(非技術)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          SQL數據庫使用JOIN的優化方法

            很早以前,也是一提到SQL Server,就覺得它的性能沒法跟Oracle相比,一提到大數據處理就想到Oracle。自己一路走來,在本地blog上記錄了很多優化方面的 post,對的錯的都有,沒有時間系列的整理出來,這篇文章將join方法的概念稍微整理在一起,給大家個參考。通過查資料了解里面提到的各種概念,在實 際中不斷驗證總結,完全可以對數據庫一步步深入理解下去的。

            我只對SQL Server 2000比較了解,但這并不阻礙我在Oracle、MySql進行SQL調優、產品架構,因為在數據庫理論原理上,各大數據庫基本出入不大,對數據庫的深入理解,也不會影響你架構設計思想變壞,相反給你帶來的是更深層次的思考。

            關于執行計劃的說明

            在SQL Server查詢分析器的Query菜單中選擇Show Execution Plan,運行SQL查詢語句,在結果窗口中有Grid、Execution Plan、Messages三個Tab??磮D形形式的執行計劃,順序是從右到左,這也是執行的順序。執行計劃中的每一個圖標表示一個操作,每一個操作都會 有一個或多個輸入,也會有一個或多個輸出。輸入和輸出,有可能是一個物理數據表、索引數據結構,或者是執行過程中的一些中間結果集/數據結構。鼠標移動到 圖標上,會顯示這個操作的具體信息,例如邏輯和物理操作名稱、記錄的數量和大小、I/O成本、CPU成本、操作的具體表達式(參數Argument)。鼠 標移動到連接箭頭上,會顯示箭頭起始端的操作輸出結果集的記錄數、記錄的大小,一般情況下可以將這個輸出結果集理解為箭頭結束端的輸入。

            另 外關于執行計劃的一些補充說明:1. 執行計劃中顯示的信息,都是一個“評估”的結果,不是100%準確的信息,例如記錄數量是取自統計信息,I/O成本、CPU成本來自執行計劃生成過程中基 于統計信息等得出的評估結果。2. 執行計劃不一定準確,一方面受SQL Server維護的統計信息準確性的影響,另一方面SQL語句編譯時刻與執行時刻的環境(內存使用狀況、CPU狀況等)可能會不一樣。

            關于統計信息、I/O成本和CPU成本的評估、SQL語句的編譯和執行過程,這里不再深入。另外盡管執行計劃不一定準確,但它仍是SQL語句分析最重要的依據,因為你可以理解為,絕大部分情況下,SQL Server是以這種方式來執行的。

            JOIN方法說明

            數據庫中,象tableA inner join tableB、tableA left out join tableB這樣的SQL語句是如何執行join操作的?就是說SQL Server使用什么算法實現兩個表數據的join操作?

            SQL Server 2000有三種方式:nested loop、merge、hash。Oracle也是使用這三種方式,不過Oracle選擇使用nested loop的條件跟SQL Server有點差別,內存管理機制跟SQL Server不一樣,因此查看執行計劃,Oracle中nested loop運用非常多,而merge和hash方式相對較少,SQL Server中,merge跟hash方式則是非常普遍。

            以SQL Server 2000為例對這三種方式進行說明,穿插在里面講解執行計劃的一些初級使用。

            1. nested loop join

            1.1 示例SQL

            select ... from tableA inner join tableB on tableA.col1=tableB.col1 where tableA.col2=? and tableB.col2=?tableA中沒有建立任何索引,tableB中在col1上有建立一個主鍵(聚集索引)。

            1.2 算法偽代碼描述

            foreach rowA in tableA where tableA.col2=?{search rowsB from tableB where tableB.col1=rowA.col1 and tableB.col2=? ;if(rowsB.Count<=0)discard rowA ;elseoutput rowA and rowsB ;}

            join操作有兩個輸入,上面例子中tableA是outer input,用于外層循環;tableB是inner input,用于循環內部。下面針對執行計劃描述一下SQL Server完成這個操作的具體步驟。 %. ^ g.L

            2vt [ AhVA

            1.3 查看執行計劃方法

            移到文章最前面。

            1.4 執行步驟

            下 面是示例SQL的執行計劃圖。 nested loop操作的右邊,位于上面的是outer input,位于下面的是inner input。你不能夠根據join中哪個表出現在前面來確定outer input和inner input關系,而必須從執行計劃中來確定,因為SQL Server會自動選擇哪個作為inner input。

          posted on 2008-02-15 14:02 lk 閱讀(1343) 評論(0)  編輯  收藏 所屬分類: DB
          主站蜘蛛池模板: 临夏县| 鄂托克前旗| 延边| 永康市| 彰武县| 三原县| 池州市| 临邑县| 阿坝县| 北票市| 宜丰县| 吉首市| 惠来县| 惠水县| 保靖县| 玉门市| 临桂县| 扶沟县| 湖南省| 山东省| 万荣县| 西乌| 平顶山市| 湘乡市| 大埔区| 宾阳县| 朔州市| 台山市| 大城县| 竹溪县| 南木林县| 高密市| 钟山县| 加查县| 垣曲县| 宝山区| 荆门市| 云浮市| 肇庆市| 那曲县| 芒康县|