1

私は単純なテーブルを持っています:

CREATE TABLE dbo.Table1 (
   ID int IDENTITY(1,1) PRIMARY KEY,
   TextField varchar(100)
)

列に非クラスター化インデックスがありTextFieldます。

両方の列を選択する単純なクエリを作成しています。次の状況がある場所の条件は次のとおりです。

...
WHERE SUBSTRING(TextField, 1, 1) = 'x'

LIKE'x%' を使用してクエリを条件に変換するか、TextField列にパーティション関数を作成する方がよいでしょうか。

パーティショニングは varchar 列の検索条件にどのように影響し、大量の行にはどのソリューションが適していますか?

4

2 に答える 2

2

デフォルトでSUBSTRING(TextField, 1, 1) = 'x'は、SARGできません。

まず、次のソリューションを使用してそのクエリをテストします (SQL プロファイラー > {SQLStatement|Batch} Completed > CPU,Reads,Writes,Duration 列)。

1)TextField列の非クラスター化インデックス:

CREATE INDEX IN_Table1_TextField
ON dbo.Table1(TextField)
INCLUDE(non-indexed columns); -- See `SELECT` columns
GO

そして、クエリは次を使用する必要がありますLIKE

SELECT ... FROM TextField LIKE 'x%'; -- Where "x" represent one or more chars.

長所/短所: キーの長さ (最大 100 文字 + UNIQUE インデックスでない場合は RowID) のため、B ツリー/インデックスには多くのレベルがあります。

2)最初の文字の計算列を作成します。

-- TextField column needs to be mandatory
ALTER TABLE dbo.Table1
ADD FirstChar AS (CONVERT(CHAR(1),SUBSTRING(TextField,1,1))); -- This computed column could be non-persistent
GO

プラス

CREATE INDEX IN_Table1_FirstChar
On dbo.Table1(FirstChar)
INCLUDE (non-indexed columns); 
GO

この場合、述語は次のようになります。

WHERE SUBSTRING(TextField, 1, 1) = 'x'

また

WHERE FirstChar = 'x'

長所/短所: キーの長さ (1 文字 + RowID) のため、B ツリー/インデックスのレベルははるかに少なくなります。述語の選択性が高い (少数の行が検証される) が、カバーされた列がない場合 (INCLUDE節を参照) に使用します。

3)したがって、列のクラスター化インデックス:FirstChar

CREATE TABLE dbo.Table1 (
   ID int IDENTITY(1,1) PRIMARY KEY NONCLUSTERED,
   TextField varchar(100) NOT NULL, -- This column needs to be mandatory
   ADD FirstChar AS (CONVERT(CHAR(1),SUBSTRING(TextField,1,1))),
   UNIQUE CLUSTERED(FirstChar,ID) 
);

この場合、述語は次のようになります。

WHERE SUBSTRING(TextField, 1, 1) = 'x'

また

WHERE FirstChar = 'x'

長所/短所: 行数が多い場合は、パフォーマンスが向上するはずです。この場合、B ツリーのレベルは最小 (1 CHAR+ 1 INT) または最小 -> 中になります。

于 2013-07-23T13:49:29.050 に答える