代码之家  ›  专栏  ›  技术社区  ›  Josh

Microsoft SQL Server能否有效地处理非持久化计算列?

  •  4
  • Josh  · 技术社区  · 15 年前

    我很难用这样一种方式来表达这个问题,即不会显示持久化的、索引的计算列的结果。

    我的问题是,如果我有这样一张桌子:

    CREATE TABLE Customers (
        ID int,
        Name nvarchar(50),
        Balance money,
        HasBalance AS CONVERT(bit, CASE WHEN Balance > 0 THEN 1 ELSE 0 END)
    )
    

    假设有一个索引,SQL查询处理器是否能有效地处理一个查询,例如:

    SELECT ID, Name, Balance
    FROM Customers
    WHERE HasBalance = 1
    

    如果计算列的表达式在一个非模式丰富的用户定义函数中呢?

    编辑

    我的例子不是很好,因为如前所述,HasBalance列不会有很好的数据分布。但是暂时忽略索引本身的效率,在选择索引和执行计划时,查询处理器是否会像下面所示那样基本上处理上面的查询?

    SELECT ID, Name, Balance
    FROM Customers
    WHERE Balance > 0
    
    1 回复  |  直到 15 年前
        1
  •  4
  •   SQLMenace    15 年前

    这取决于数据的分布,现在你只有2个可能的值1和0……所以除非你有99%的数据是一个值,否则你的选择性会很差,然后它必须扫描整个索引来找到所有的正值或负值

    编辑…..这里是发生的,你得到一个表扫描

    CREATE TABLE Customers (
        ID int,
        Name nvarchar(50),
        Balance money,
        HasBalance AS CONVERT(bit, CASE WHEN Balance > 0 THEN 1 ELSE 0 END)
    )
    
    
    insert Customers values(1,'d',100)
    insert Customers values(2,'d',-2)
    insert Customers values(3,'d',-4)
    insert Customers values(4,'d',3)
    insert Customers values(5,'d',5)
    
    create index ix_test on Customers(Balance)
    
    
    SELECT ID, Name, Balance
    FROM Customers
    WHERE HasBalance = 0
    
    set showplan_text on
    

    |--表扫描(对象:([master].[dbo].[Customers]), 其中:(CONVERT(bit,CASE WHEN[master].[dbo].[Customers].[Balance]>($0.0000) 则(1)ELSE(0)END,0)=[@1]))

    看看这个

    SELECT Balance
    FROM Customers
    WHERE HasBalance = 0
    

    -- (对象:([master].[dbo].[Customers].[ix_test]),其中:(CONVERT(bit,

    SELECT Balance
    FROM Customers
    WHERE Balance > 0
    

    |-- 索引查找 (对象:([master].[dbo].[Customers].[ix\u test]),SEEK:([master].[dbo].[Customers].[Balance]>转换\u(money,[@1],0))顺序(向前)

    推荐文章