SQL Server 2005合并聯接最佳使用情況
以下的文章主要描述的是SQL Server 2005合并聯接的正確算法,在實際操作中如果遇到兩個聯接輸入而且不小但已在二者,其聯接列上排序(例如,如果它們是通過掃描已排序的索引獲得的),則合并聯接是最快的聯接操作。
如果兩個聯接輸入都很大,而且這兩個輸入的大小差不多,則預先排序的SQL Server 2005合并聯接提供的性能與哈希
如果兩個聯接輸入并不小但已在二者聯接列上排序(例如,如果它們是通過掃描已排序的索引獲得的),則合并聯接是最快的聯接操作。如果兩個聯接輸入都很大,而且這兩個輸入的大小差不多,則預先排序的SQL Server 2005合并聯接提供的性能與哈希聯接相近。
從上次我們分析來看,嵌套循環適合輸入和輸出都小的情況,那如果輸入和輸入都比較大情況下,使用合并算法什么情況下最優。
最佳使用:
合并聯接本身的速度很快,但如果需要排序操作,選擇SQL Server 2005合并聯接就會非常費時。然而,如果數據量很大且能夠從現有 B 樹索引中獲得預排序的所需數據,則合并聯接通常是最快的可用聯接算法。
我們來測試一下,合并連接的最優情況:
測試環境:表:workflowinfo1 約45萬條 表workflowbase1 約4.5萬條
條件:workflowbase1中列id,creater都建立索引,workflowinfo1中workflowid建立了索引。
如果兩個聯接輸入并不小但已在二者聯接列上排序(例如,如果它們是通過掃描已排序的索引獲得的),則SQL Server 2005合并聯接是最快的聯接操作。如果兩個聯接輸入都很大,而且這兩個輸入的大小差不多,則預先排序的合并聯接提供的性能與哈希聯接相近。~:(creater=4028814110830a1e01108fe379e60061’的workflowbase1表有1023條數據)
測試語句:
合并算法
- select a.* from workflowbase1 a inner merge join dbo.workflowinfo1 b
- on a.id=b.workflowid and a.creater='4028814110830a1e01108fe379e60061'
hash算法
- select a.* from workflowbase1 a inner hash join dbo.workflowinfo1 b
- on a.id=b.workflowid and a.creater='4028814110830a1e01108fe379e60061'
注意:這兩條SQL和上一個嵌套循環的例子有區別,一個 select * 和一個是 select a.*
重啟數據庫服務,查看成本:
執行結果:
(10468 行受影響)
表'workflowinfo1'。掃描計數1,邏輯讀取3527 次,物理讀取1 次,預讀3528 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
表'workflowbase1'。掃描計數1,邏輯讀取1571 次,物理讀取0 次,預讀1624 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
(10468 行受影響)
表'workflowbase1'。掃描計數3,邏輯讀取1571 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
表'workflowinfo1'。掃描計數3,邏輯讀取3886 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
表'Worktable'。掃描計數0,邏輯讀取0 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
這,時,Merge算法比Hash算法少了357次IO。這時發現,成本對比,合并連接要優于hash連接,排序使用了B-tree索引的排序,大表workflowinfo1就沒有排序操作。
這里驗證了上面的一句話:
如果數據量很大且能夠從現有 B 樹索引中獲得預排序的所需數據,則SQL Server 2005合并聯接通常是最快的可用聯接算法
如果我們換一下,將select a.*換成select *, 看看成本
這里hash連接是最優的算法
執行結果:
(10468 行受影響)
表'workflowbase1'。掃描計數3,邏輯讀取1571 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
表'workflowinfo1'。掃描計數3,邏輯讀取9604 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
(10468 行受影響)y
表'Worktable'。掃描計數0,邏輯讀取0 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
表'workflowinfo1'。掃描計數1,邏輯讀取9604 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
表'workflowbase1'。掃描計數1,邏輯讀取1571 次,物理讀取0 次,預讀0 次,lob 邏輯讀取0 次,lob 物理讀取0 次,lob 預讀0 次。
這里的hash和merge的io次數一樣,但merge連接里多了一個排序操作,占到整個成本的60&,的確驗證了上面的一句話:
合并聯接本身的速度很快,但如果需要排序操作,選擇SQL Server 2005合并聯接就會非常費時。
兩個聯接輸入并不小但已在二者聯接列上排序,則SQL Server 2005合并聯接是最快的聯接操作。如果沒有排序hash連接是最優的操作。
注意:這里的排序指兩個輸入集合必須按相等列進行分別排序。而不是按其他列排序。
【編輯推薦】
- SQL Server2000連接錯誤的緣由有哪些?
- SQL Server實例中對另個實例的調用
- SQL Server 2000的安全策略的正確打造
- SQL Server 數據導入的實際行為規范描述
- MS SQL Server問題與其正確解答方案