web-dev-qa-db-ja.com

単一のテーブルをクエリするときにカーディナリティの問題が発生するのはなぜですか

次のクエリがあります。

SELECT
    [iri].[RateItemKey],
    [iri].[RateItemType]
FROM
    [prism72].[dbo].[ispRateItem] AS [iri]
WHERE
    [iri].[Status] = 1
    AND (
        [iri].[RateItemType] IN (3,2)
    )

IspRateItemテーブルには次のインデックスがあります。

CREATE NONCLUSTERED INDEX [COVIX_ispRateItem_RateItemType_Status] ON [dbo].[ispRateItem] 
(
    [Status] ASC,
    [RateItemType] ASC
)
INCLUDE ( [RateItemKey]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

CREATE UNIQUE CLUSTERED INDEX [CLIX_ispRateItem] ON [dbo].[ispRateItem] 
(
    [RateItemKey] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

ALTER TABLE [dbo].[ispRateItem] ADD  CONSTRAINT [RateItem_PK] PRIMARY KEY NONCLUSTERED 
(
    [RateItemKey] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
GO

以下を使用して統計を更新しました:

UPDATE STATISTICS [ispRateItem] WITH FULLSCAN, ALL;

ただし、同じカーディナリティの問題が発生するテーブルにインデックスを付けます:Est Rows 1565、Actual Rows4315。すべてのインデックスを削除しようとしました(テーブルスキャンが発生しました)。

何が原因でしょうか?

私はクエリチューニングの初心者であることに注意してください。

ありがとう。

アラン

2
Alan T

あなたの問題は、あなたのWHERE句が同じテーブルに複数の述語を持っているという事実だと思います。 This PaulWhiteの記事で問題が説明されています。

現在のWHERE句が実行することを実行するcomputed columnを使用することで、この問題を回避できる可能性があります。その後、この列を単独で使用できますが、正常に機能することを確認するには、少しテストが必要です。

解決策:

Jamesの提案により、私は複数の述語の問題を調査するようになりました。そのため、単一の述語を使用してテストしたところ、RateItemTypeフィールドのvarcharとして整数が格納されていることがわかりました。

この問題は、次の変更を加えることで解決されました。

[iri].[RateItemType] IN (3,2)

[iri].[RateItemType] IN ('3','2')
2
James Anderson