8

クエリの検索引数に CHECKSUM 列が明示的に含まれていない限り、SQL Server は自動的に CHECKSUM/ハッシュ インデックスを使用しないようです。これは問題です。なぜなら、私はテーブルをクエリするアプリケーションを制御しておらず、そのパフォーマンスを損なわない可能性があるからです。

クエリを変更して新しい CHECKSUM/ハッシュ カラムを含めに、SQL Server に新しい CHECKSUM/ハッシュ インデックスを使用させる方法はありますか?

再現スクリプト

CREATE TABLE big_table
(
    id BIGINT IDENTITY CONSTRAINT pk_big_table PRIMARY KEY,
    wide_col VARCHAR(50),
    wide_col_checksum AS CHECKSUM(wide_col),
    other_col INT
)

CREATE INDEX ix_checksum ON big_table (wide_col_checksum)

いくつかのテスト データを挿入します。

SET NOCOUNT ON
DECLARE @count INT = 0
BEGIN TRANSACTION
WHILE @count < 10000
BEGIN
    SET @count = @count + 1
    INSERT INTO big_table (wide_col, other_col) 
    VALUES (SUBSTRING(master.dbo.fn_varbintohexstr(CRYPT_GEN_RANDOM(25)), 3, 50), @count)
    IF @count % 1000 = 0
    BEGIN
        COMMIT TRANSACTION
        BEGIN TRANSACTION
    END
END
COMMIT TRANSACTION

INSERT INTO big_table (wide_col, other_col) 
VALUES ('ABCDEFGHIJKLMNOPQRSTUVWXYZ', 9999999)

レガシー クエリ。Clustered Index Scan (BAD) の原因:

SELECT * FROM big_table 
WHERE wide_col = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

クラスタ化インデックス スキャン (BAD)


クエリを更新しました。NonClustered Index Seek の原因 (良い):

SELECT * FROM big_table 
WHERE wide_col = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
AND wide_col_checksum = CHECKSUM('ABCDEFGHIJKLMNOPQRSTUVWXYZ')

NonClustered Index Seek (良い)

バックグラウンド

私のテーブルは非常に大きく (数億行)、いくつかのインデックス (~ 20) があり、そのすべてが必要です。インデックス付きの列の一部は少し幅が広く (~ 50 バイト)、重複する値がほとんどありません。列は等しい場合にのみ検索されます。テーブルは常に挿入されます。

上記のサンプル テーブルの「通常の」インデックスと CHECKSUM/ハッシュ インデックスを比較したテーブルを次に示します。100 万行のテーブルで新しく再構築されたインデックスからのデータ:

ハッシュ インデックスと圧縮

ページ圧縮だけでは、サンプル データにはほとんど効果がありません (実際のデータはもう少し圧縮率が高くなるはずです)。ハッシュ インデックスは、4 分の 1 のインデックス サイズ削減を達成します。ハッシュ インデックスのページ圧縮により、インデックス サイズが 6 分の 1 に縮小されます。

ハッシュインデックスを使用する私の目的は次のとおりです。

  1. メモリ内のこれらのインデックスのサイズを縮小して、SQL Server が RAM 内により多くの部分をキャッシュできるようにし、物理的な読み取りを回避します。
  2. インデックスのストレージ サイズを減らします。
  3. INSERT 操作のインデックス I/O を減らします。
4

4 に答える 4

1

SQL Server は、チェックサム/ハッシュ インデックスを使用して自動的に起動しません。クエリは、インデックスの使用を検討するために、SQL Server のハッシュされた列を使用する必要があります。したがって、クエリを変更するという目的を達成する方法がわかりません。これは興味深い質問ですが、SQL Server への良い機能要求になる可能性があります。

于 2014-09-23T10:14:25.873 に答える
1

アプリケーションが次のクエリを実行する場合:

SELECT * FROM big_table WHERE wide_col = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

wide_colではなくのインデックスが必要ですwide_col_checksum

SQL Server は、インデックスを B ツリーとして格納します。@MartinSmith が示唆するように、インデックス内の列のサイズを小さくすると、実際にメモリとディスクのフットプリントが減少します。

于 2012-06-18T13:44:30.687 に答える
0

ほとんどの照合では、2 つのクエリは異なる結果を返す可能性があります。これは'A'='a'、 がCHECKSUM('A')と等しくないためCHECKSUM('a')です。CS_AS または BIN 照合でも、末尾のスペースが問題になる可能性があります。そのため、SQL Server はそのようなインデックスを自動的に使用できません。

于 2019-04-29T04:11:26.080 に答える