解释包含位图筛选器的执行计划
使用位图筛选的并行查询执行计划在一个或多个运算符子树上具有位图运算符。位图筛选器使用运算符树某部分的表中一组值的简洁表示形式来筛选位于该树另一部分的第二张表中的行。通过在查询中预先删除不必要的行,后续运算符将处理较少的行,从而提高查询的整体性能。
在 SQL Server 2008 中,可在优化后将位图筛选引入并行查询计划(这与在 SQL Server 2005 中相同),或者在查询计划生成期间通过查询优化器动态引入位图筛选。当动态引入筛选器时,此筛选器即被称为“已优化的位图筛选器”。查询计划既可包含位图筛选器,又可包含已优化的位图筛选器。查询优化器将确定位图筛选器或已优化的位图筛选器的选择性何时可满足使用条件以及在哪些运算符上应用筛选器。有关详细信息,请参阅通过位图筛选优化数据仓库查询性能。
当分析包含位图筛选的执行计划时,了解数据在计划中的流动方式以及筛选的应用位置是十分重要的。位图筛选器和已优化的位图是在哈希联接的生成输入(维度表)侧创建的;但是,实际筛选通常是在 Parallelism 运算符中完成,该运算符位于哈希联接的探测输入(事实数据表)侧。不过,如果位图筛选器是基于整数列的,则筛选器可直接应用于初始表或索引扫描操作,而不是 Parallelism 运算符。此技术称为行内优化。
查看显示计划中的位图筛选器
若要查看查询计划中的位图筛选器,请使用 SET 选项 SHOWPLAN_ALL、SHOWPLAN_TEXT 或 SHOWPLAN_XML,或在 SQL Server Management Studio 中单击**“包括实际的执行计划”**。
如果生成了 XML 显示计划,则物理和逻辑位图运算符将通过以下方式列出:
<RelOp NodeId="2" PhysicalOp="Bitmap" LogicalOp="Bitmap Create" EstimateRows="88" EstimateIO="0" EstimateCPU="0.0718125" AvgRowSize="6893" EstimatedTotalSubtreeCost="0.229385" Parallel="1" EstimateRebinds="0" EstimateRewinds="0">
应用了位图筛选器的运算符在 Probe Column 属性中包含有位图的名称。
应用了已优化的位图筛选器的运算符包含位图谓词,其格式为 PROBE([Opt_Bitmap1001], {[column_name]} [, 'IN ROW'])。位图谓词可报告以下信息:
与 Bitmap Create 运算符中引入的名称相对应的位图名称。前缀“Opt_”表示使用了已优化的位图筛选器。
探测的列。这是已筛选数据流过树时所经过的点。
位图探测是否是在行内执行。如果使用行内优化,则使用 IN ROW 参数调用位图探测。否则将缺失此参数。
示例
下面的示例演示如何在执行计划中使用已优化的位图筛选。以下两个维度表 DimProduct 和 DimCustomer 通过对单个整数列使用主键到外键联接从而联接到事实数据表 FactInternetSales。
USE AdventureWorksDW;
GO
SELECT *
FROM dbo.FactInternetSales AS F
INNER JOIN dbo.DimProduct AS D1 ON F.ProductKey = D1.ProductKey
INNER JOIN dbo.DimCustomer AS D2 ON F.CustomerKey = D2.CustomerKey
WHERE D1.StandardCost <= 30 AND D2.YearlyIncome <= 50000;
下图表示在扫描维度表并且已获知消除事实数据表中不符合要求的行所需的信息之后,在两张维度表的运算符子树中创建了一个已优化的位图筛选器。然后筛选器将应用于事实数据表中的最早位置,即 Table Scan 运算符。Table Scan 属性的谓词部分显示了筛选器的应用。谓词中显示的信息说明同时使用了已优化的位图筛选器 Opt_Bitmap1008 和 Opt_Bitmap1009 来限制从事实数据表中返回的行。在事实数据表中探测的列以 [F].[CustomerKey] 和 [F].[ProductKey] 的形式列出。图中显示了 IN ROW 参数,这说明在进程中使用了行内优化。如果无法执行行内优化,则位图筛选将应用于 Parallelism 运算符。
从该图中可得出以下结论:
已优化的位图筛选器是在两个子树中创建的。
两个筛选器均动态应用于单个 (Table Scan) 运算符。
首先实现预计其选择性最大的已优化的位图筛选器。
维度表联接到事实数据表时所基于的列可使用行内优化。也就是说,联接是基于单个整数列的。
筛选器将尽可能应用在查询中最早的点,因为这样可减少流过从 Table Scan 操作到树中其余运算符的行数。