为什么READPAST提示导致索引视图被忽略?


10

我正在研究使用READPAST提示来减少应用程序财务子系统中的资源锁定。

这似乎是个好方法,因为金融交易记录仅被添加,从未更新或删除。唯一会被跳过的行是在事务内部插入的全新行。在交易落实之前,它们实际上不存在于外界。

但是,我注意到使用READPAST提示的索引视图的查询性能较差。比较查询计划时,它看起来像是带有提示,查询优化器选择不使用索引视图,而是退回到将其视为常规视图。

我不确定为什么会这样。我想象索引视图与任何其他索引一样,可以在操作期间锁定键,并且添加操作READPAST也可以类似。

SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa WITH (READPAST)
WHERE isa.TotalOwedAmount = 0.0

在此处输入图片说明

SELECT TOP 1 isa.InvoiceId
FROM Financial_InvoiceSummaryAmounts isa
WHERE isa.TotalOwedAmount = 0.0

在此处输入图片说明

添加NOEXPAND提示似乎也可以,但是我有兴趣了解更多有关为什么可能READPAST导致查询优化器首先做出选择的原因(作为完整答案的一部分)。

Answers:


7

重用我的文章Enterprise Edition中使用NOEXPAND提示的另一个原因的示例表和索引视图:

CREATE TABLE dbo.T
(
    col1 integer NOT NULL
);
GO
INSERT dbo.T WITH (TABLOCKX)
    (col1)
SELECT 
    SV.number
FROM master.dbo.spt_values AS SV
WHERE 
    SV.type = N'P';
GO
CREATE VIEW dbo.VT
WITH SCHEMABINDING
AS
SELECT T.col1 
FROM dbo.T AS T;

复制

此查询与索引视图匹配(尽管具有冗余聚合):

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT;

索引视图匹配

添加READPAST提示会导致访问基表:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST);

索引视图不匹配

说明

READPAST提示是语义的影响。优化器拒绝重写查询,以使结果改变。为了显示:

以下查询执行没有问题:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST);

然而:

SELECT DISTINCT
    VT.col1 
FROM dbo.VT AS VT 
    WITH (READPAST)
OPTION 
    (TABLE HINT (VT, FORCESCAN));

产生错误:

Msg 8722,第16级,状态1,第42行
无法执行查询。
语义影响提示“ readpast”出现在对象“ VT”的“ WITH”子句中
但不在相应的“ TABLE HINT”子句中。
更改OPTION(TABLE HINTS ...)子句,以使语义影响提示
与WITH子句匹配。

当您引用没有NOEXPAND提示的索引视图时,该视图将被扩展(在编译和优化开始之前)以引用基础对象。在此过程的后期,优化器可能会考虑将查询树全部或部分匹配回索引视图。

READPAST不使用时NOEXPAND,提示会传播到基表,从而防止视图匹配(不同的语义)。

使用NOEXPAND,提示将直接应用于视图,因此没有问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.