有資料表company,跟products表,分別是企業表跟產品表,每個企業有0個或多個產品,現在需要選出有產品的企業,
sql查詢如下
select username,id from company as t
where
t.attproperty='00000000000000001000' and t.templateid=3
and
exists(select * from products where products.companyid=t.id) 或
select username,id from company as t
where
t.attproperty='00000000000000001000' and t.templateid=3
and t.id in(select companyid from product group by companyid)
這兩句的執行計畫其實是一樣的,如下圖:
首先是表掃瞄,分別掃瞄company表跟products表,掃瞄時會根據表的主鍵(pk)逐行進行.
1.掃瞄company表:
掃瞄company表時將根據id列(company的主鍵列),逐行取出,判斷attproperty='00000000000000001000' 並且 templateid=3
因為id是主鍵,主鍵是建立聚集索引的,而聚集索引是有序的(這裡id是int型別所以按數字大小徘序),掃瞄完company表的結果是乙個按id排序的記錄集rs(id,user)
2.掃瞄products表並構建hash表:
同樣根據products表的主鍵(也是名為id的列)逐行取出,根據每行的comanpyid(companyid是對應於company
.id的外來鍵),建立hash表,將從products中取出的每一行根據companyid新增到hash中來,最後我們就得到乙個按companyid為鍵進行檢索的hash表了,由於掃瞄products表使用的products.id的順序,因此最後得到hash表中companyid並不是按順序排列的.
3.排序hash表
根據companyid對hash表進行排序
4.merge join
merge join 是將兩個已經排好序的表,進行匹配,邏輯上就是乙個inner join, 排序好的表進行匹配時只需選擇一記錄數較小的表(取名為a),取其第乙個記錄,使用這個記錄從另外一張表(取名為b)進行查詢,由於是排序好的序列,可以進行二分查詢,找到後,記下b表此記錄的位置(設定位indexb0) 這樣a表第二條記錄在b表進行二分查詢時,其左索引就從indexb0開始.如果a表的某條記錄在b表中無法匹配那麼整個匹配就完成了.
當然在a表記錄跟b表記錄匹配度很高時(比方完全一樣)那麼做順序查詢可能效率更高,當然我無法知道mssql內部具體的實現,以上只是自己的猜測而已,如有不當,望多兼諒!
可以看到sql語句最後變成集合操作,而集合操作中又離不開,排序,查詢...這些基本操作,學校出來好幾年了,每天接觸的多是sql語句,今天默然發現他們早在sql中了,-_"
MSSQL執行計畫的優化建議
執行計畫 提交sql語句,資料庫查詢優化器,經過分析生成,制定多個查詢方式,從中選擇資源使用最少的 資料庫制定執行計畫是按照使用資源最少,而不是時間最短 對應的意思 1 受影響的行數 2 影響的位元組數 3 影響的資料大小 執行計畫 1 table scan 全表掃瞄 效能最差 2 cluster ...
oracle如何看執行計畫
文章寫的不錯,原文請看 另外,最近公司舉行sql優化大賽,下面是自己的一些總結 1.首先要理解sql的意圖,這樣才能等價的改寫出sql 2.要保證執行的正確性 比如這次的left join,還有上次的建立序列 3.建立索引是第一步,建立索引後要考慮索引能否被用到 執行計畫是否走所建的索引,索引欄位上...
MS SQL 通過執行計畫來分析SQL效能
suta2008 ms sql 通過執行計畫來分析sql效能 如何知道一句sql語句的執行效率呢,只知道下面3種 1 通過sql語句執行時磁碟的活動量 io 資訊來分析 set statistics io on 開啟 set statistics io off 關閉 3 通過執行計畫檢視 ctrl ...