2010-08-13 55 views
4

我很难用这样一种方式来表达这个问题,而这种方式对于持久的索引计算列没有调整结果。Microsoft SQL Server能否有效地处理非持久计算列?

我的问题是,如果我有一个表,如:

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 

回答

4

这取决于数据的分布,现在你只有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 

| --Table扫描(OBJECT :([master]。[dbo]。[Customers]), WHERE:(CONVERT(bit,CASE WHEN [master]。[dbo]。[Customer 。s]的[平衡]>($ 0.0000产品) THEN(1)ELSE(0)END,0)= [@ 1]))

和看看这个

SELECT Balance 
FROM Customers 
WHERE HasBalance = 0 

- 索引扫描(OBJECT:([master]。[dbo]。[Customers]。[ix_test]),WHERE:(CONVERT(位, CASE WHEN [master]。[dbo]。[Customers]。[Balance]> ($ 0.0000产品)THEN(1)ELSE(0)END,0)= [@ 1]))

SELECT Balance 
FROM Customers 
WHERE Balance > 0 

| - 索引查找(OBJECT:([master]。[dbo]。[Customers]。[ix_test]),SEEK :([master]。[dbo]。[Customers]。[Balance]> CONVERT_IMPLICIT(money,[@ 1], 0))ORDERED FORWARD)

+0

我更新了我的问题以添加更多的上下文,在那段时间里我看到你已经非常了解你的编辑。所以看起来这两个查询不会被视为相同。 – Josh 2010-08-13 19:34:32