1

Luceneを使用してCMSのコンテンツのインデックスを作成している最中なので、SQL Serverデータベーススキーマを拡張して「IsIndexed」ビット列を追加しました。これにより、Luceneインデクサーはまだ作成されていないコンテンツを見つけることができます。インデックス付き。

テーブルにインデックスを追加したので、列Contentの検索が高速になります。IsIndexedデータベースは次のようになります。

CREATE TABLE Content (
    DocumentId bigint,
    CategoryId bigint,
    Title nvarchar(255),
    AuthorUserId bigint,
    Body nvarchar(MAX),
    IsIndexed bit
)
CREATE TABLE Users (
    UserId bigint,
    UserName nvarchar(20)
)

次のインデックスが存在します。

Content (
    PK_Content (Clustered) : DocumentId ASC
    IX_CategoryId (Non-Unique, Non-Clustered) : CategoryId ASC
    IX_AuthorUserId (Non-Unique, Non-Clustered) : AuthorUserId ASC
    IX_Indexed_ASC (Non-Unique, Non-Clustered) : IsIndexed ASC, DocumentId ASC
    IX_Indexed_DESC (Non-Unique, Non-Clustered) : IsIndexed DESC, DocumentId ASC
)

Users (
    PK_Users (Clustered) : UserId
)

これは、インデックス付けされていないコンテンツを検索するために使用されるクエリです。

SELECT
    TOP 1
    Content.DocumentId,
    Content.CategoryId,
    Content.Title,
    Content.AuthorUserId,
    Content.Body
    Users.UserName
FROM
    Content
    INNER JOIN Users ON Content.AuthorUserId = Users.UserId
WHERE
    IsIndexed = 0

ただし、実行すると、実際の実行プランは、PK_Contentのクラスター化インデックススキャンとPK_Usersのクラスター化インデックスシークを組み合わせて報告します。クエリの実行には約300ミリ秒かかります。

クエリを変更してUsers.UserNameフィールドとUsers内部結合を削除すると、クエリの実行に約60ミリ秒かかり、PK_Contentのクラスター化インデックススキャンはなく、クラスター化インデックスのみがPK_Contentをシークします。

列の降順インデックスを追加する前後にこれを試し、IX_IndexedインデックスContent.IsIndexedにも追加しましたが、違いはありませんでした。Content.DocumentId

私は何が間違っているのですか?必要なすべてのインデックス(そしていくつか)を作成しました。Contentテーブルには、Usersテーブルと同様に数十万の行があるため、オプティマイザーがスキャンを選択する理由がわかりません。

4

2 に答える 2

2

IsIndexedフィールドとフィールドの両方でコンテンツにインデックスを追加するとAuthorUserId、シークが実行されます。SQL サーバーのバージョンによってINCLUDEは、選択で使用しているフィールドを含むステートメントを追加して、速度を向上させることができます。

IX_Indexed_AuthorUserId (非一意、非クラスター化) : IsIndexed、AuthorUserId

于 2012-06-28T14:42:53.147 に答える
1

このような選択性の低い列 (0 と 1 の 2 つの値のみ) のインデックスは常に無視されます。転換点を参照してください。1 つのオプションは、それをクラスター化インデックスの左端のキーとして移動し、DocumentId の主キー制約を非クラスター化インデックスにすることです。

CREATE TABLE Content (
    DocumentId bigint,
    CategoryId bigint,
    Title nvarchar(255),
    AuthorUserId bigint,
    Body nvarchar(MAX),
    IsIndexed bit,
    constraint pk_DocumentId primary key nonclustered (DocumentId)
)

create unique clustered index cdxContent on Content (IsIndexed, DocumentId);

別のオプションは、フィルタリングされたカバリング インデックスを作成することです。

create unique index nonIndexedContent on Content (DocumentId)
  include (CategoryId, Title, AuthorUserId, Body)
  where IsIndexed = 0;

この 2 番目のオプションでは、多くのコンテンツが複製される可能性があります。個人的には、最初のオプションを使用します。

于 2012-06-28T14:48:13.127 に答える