4

永続化され、インデックスが付けられた計算列の結果が表示されないような方法でこの質問を表現するのに苦労しています。

私の質問は、次のようなテーブルがあるかどうかです。

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

Balanceにインデックスがあるとすると、SQLクエリプロセッサは次のようなクエリを効率的に処理しますか。

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

クエリでケースを直接指定したかのように、計算された列式を本質的に「インライン化」しますか?

計算列の式がスキーマにバインドされていないユーザー定義関数にある場合はどうでしょうか。

編集

前述のように、HasBalance列にはデータの分散があまり良くないため、私の例はあまり良くありませんでした。しかし、インデックス自体の効率を少し無視すると、クエリプロセッサは、インデックスを選択して実行プランを選択するときに、基本的に上記のクエリを次のように処理しますか?

SELECT ID, Name, Balance
FROM Customers
WHERE Balance > 0
4

1 に答える 1

4

これはデータの分布に依存します。現在、可能な値は1と0の2つだけです。したがって、データの99%が1つの値でない限り、選択性は非常に低くなり、全体をスキャンする必要があります。すべての正または負の値を見つけるためのインデックス

編集.....これが何が起こるかです、あなたはテーブルスキャンを取得します

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 Scan(OBJECT:([master]。[dbo]。[Customers])、WHERE:(CONVERT(bit、CASE WHEN [master]。[dbo]。[Customers]。[Balance]>($ 0.0000) THEN(1)ELSE(0)END、0)= [@ 1]))

そしてこれを見てください

SELECT Balance
FROM Customers
WHERE HasBalance = 0

--インデックススキャン(OBJECT:([master]。[dbo]。[Customers]。[ix_test])、WHERE:(CONVERT(bit、CASEWHEN[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))順方向に注文)

于 2010-08-13T19:18:38.090 に答える