2010-08-13 59 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