1

結合する必要がある 2 つの大きなテーブルに一意のクラスター化されたインデックスを作成しましたが、これらのインデックスは、クエリ プランから明らかなように使用されません。ヒントでこれらのインデックスの使用を強制すると、インデックス スキャンが使用され、パフォーマンスが大幅に低下します。1 つのテーブルの一意のキーが 2 番目のテーブルの外部キーであるため、これは私を困惑させます。これがスキーマです。2 つのテーブルはLOCPOLです。LOC700 万の奇数行がありPOL、600 万行を超えています。

CREATE TABLE [dbo].[LOC](
    [acct_num] [char](30) NOT NULL,
    [cntr_num] [char](30) NOT NULL,
    [lob_cde] [char](2) NOT NULL,
    [ste_locn_nme] [char](30) NOT NULL,
    [buldg_num] [char](20) NOT NULL,
    [prctr_cde] [char](3) NULL,
        ...more fields...
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_All] ON [dbo].[LOC] 
(
    [acct_num] ASC,
    [cntr_num] ASC,
    [lob_cde] ASC,
    [buldg_num] ASC,
    [prctr_cde] ASC,
    [spcl_cond_1_id] ASC,
    [spcl_cond_2_id] ASC,
    [spcl_cond_3_id] 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]

CREATE UNIQUE CLUSTERED INDEX [IDX_LOC_PKEY] ON [dbo].[LOC] 
(
    [acct_num] ASC,
    [lob_cde] ASC,
    [prctr_cde] ASC,
    [cntr_num] ASC,
    [ste_locn_nme] ASC,
    [buldg_num] 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]

... more non-unique indices on LOC, each on single columns: buldg_num, prctr_cde, acct_num

CREATE TABLE [dbo].[POL](
    [acct_num] [char](30) NOT NULL,
    [cntr_num] [char](30) NOT NULL,
    [lob_cde] [char](2) NOT NULL,
    [prctr_cde] [char](3) NULL,
        ...more fields...
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IDX_All] ON [dbo].[POL] 
(
    [acct_num] ASC,
    [cntr_num] ASC,
    [lob_cde] ASC,
    [prctr_cde] ASC,
    [acct_nme] 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]

CREATE UNIQUE CLUSTERED INDEX [IDX_POL_PKEY] ON [dbo].[POL] 
(
    [acct_num] ASC,
    [lob_cde] ASC,
    [prctr_cde] ASC,
    [cntr_num] 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]

... more non-unique indices on POL, each on single columns: cntr_num, prctr_cde

ご覧のとおり、POL テーブルの一意のキー ( acct_num, lob_cde, prctr_cde, cntr_num) の 4 つのフィールドは、テーブルの主キーの最初の 4 つの列ですLOC。これら 2 つのテーブルを結合する多くのクエリと同様に、実行したい 1 つのクエリを次に示します。

select 
      [Easy matches] = COUNT(*)
FROM LOC INNER JOIN POL ON (
        LOC.acct_num = POL.acct_num 
    AND LOC.lob_cde = POL.lob_cde 
    AND LOC.prctr_cde = POL.prctr_cde
    AND LOC.cntr_num = POL.cntr_num)

ヒントがなければ、これはIDX_prctr_cde各テーブルのインデックスを使用するのが好きです。このprctr_cde列はあまり選択的ではありません。LOCまたはPOLテーブルには 7 つの異なる値しかありません。クエリでインデックスを使用する必要があることを示唆した場合IDX_cntr_num、それは非常に選択的な列 (各テーブルに 600 万を超える個別の値) であるため、良好なパフォーマンスが得られます。acct_numは とほぼ同じくらい選択的でcntr_num、600 万を超える個別の値があります。

非選択インデックスがデフォルトで使用されるのはなぜですか? 一意のクラスター化インデックスの使用に切り替えると、クエリの実行が大幅に遅くなるのはなぜですか? (10 倍、20 倍、さらには 30 倍遅くなります。)

注:私が使用したヒントは次のとおりです。

OPTION ( 
        TABLE HINT(POL, INDEX (IDX_POL_PKEY)),
        TABLE HINT(LOC, INDEX (IDX_LOC_PKEY))
       )

注: SQL Server 2005 と SQL Server 2008 を使用しています。

4

0 に答える 0