本文首先介紹了在 Microsoft® SQL Server 7.0 的查詢優化中位圖的使用,然後介紹了它們在 SQL Server 2000™ 中增強的應用。
Microsoft SQL Server 7.0 在所有的散列聯接中無提示使用位圖。散列聯接包含創建和探測兩個階段。在創建階段,其中一個已聯接的表(也稱為外部表)的所有聯接鍵都被分布到一個散列表中。作為該散列操作的副產品,SQL Server 將生成一個獨立的位圖,其中“0”表示“外部表中沒有鍵值分布到該位”,“1”表示“外部表中有一個或多個鍵值分布到該位”。
位圖的大小是在根據外部表中唯一值的數量而進行的優化查詢過程中決定的。一旦外部表中所有的行都被散列後,位圖就由 0 和 1 組成。然後將使用與處理外部鍵相同的散列算法對探測表(也稱為內部表)中的每個鍵進行分布。
在檢查和搜索創建階段的散列表之前,我們將先檢查位圖。如果對應的條目為“0”,則該行在外部表中不可能有匹配值,因此將被丟棄。
由於搜索位圖要比搜索散列表更經濟,處理不生成聯接記錄的內部表中的行要比處理不帶位圖的行快。由於位圖是散列聯接不可分割的一部分,因此位圖將自動創建並且不會顯示在顯示方案的輸出中。
Microsoft SQL Server 2000 非常有效地使用了類似的位圖,不僅在內部散列聯接中使用,而且還用於外部聯接運算符以刪除包含不能生成任何聯接記錄的鍵值的行。在創建位圖的顯示方案輸出中,有一個“Bitmap Create”運算符。在查詢優化過程中,位圖被自動引用到查詢計劃中。以下查詢示例便使用了包含這些位圖的計劃:
SELECT S_NAME, S_ADDRESS ,S_PHONE ,S_COMMENT ,PS_PARTKEY
FROM SUPPLIER ,PARTSUPP
WHERE S_SUPPKEY = PS_SUPPKEY AND
PS_PARTKEY between 5000 AND 5999
該查詢從 SUPPLIER 表中選擇所有供應商,這些供應商生產 5000 系列中的所有部件(部件鍵值在 5000 到 5999 之間)。除 SUPPLIER 表外,我們還使用 PARTSUPP(部件供應商)表,它包含了(針對每個部件)生產同一部件的不同供應商的所有記錄。圖 1 顯示了由 SQL Server 2000 生成的顯示方案圖解。
圖 1:示例查詢的執行計劃圖解
對於每個數據流,位圖都在聯接的外部輸入端上的散列聯接之前創建。從左至右和從上至下查看上面的顯示計劃圖解,將發現 PARTSUPP 表的掃描是並行的。後面的交換運算符 (Parallelism/Repartition Streams) 使用鍵值分配行,這樣它們將在並行的散列匹配(聯接)之前被置於包含 SUPPLIER 表的再分配行的對應流中。先執行頂部分支,直至散列聯接的散列表被填充,底部分支沒有活動為止。