0

次の表があります。

CREATE TABLE [Cache].[Marker](
    [ID] [int] NOT NULL,
    [SubID] [varchar](15) NOT NULL,
    [ReadTime] [datetime] NOT NULL,
    [EquipmentID] [varchar](25) NULL,
    [Sequence] [int] NULL
) ON [PRIMARY]

そして、次のインデックス:

CREATE UNIQUE CLUSTERED INDEX [IX_Marker_EquipmentID_ReadTime_SubID] ON [Cache].[Marker] 
(
    [EquipmentID] ASC,
    [ReadTime] ASC,
    [SubID] ASC
)

CREATE NONCLUSTERED INDEX [IX_Marker_Id] ON [Cache].[Marker] 
(
    [ID] ASC
)
INCLUDE ( [EquipmentID]) 

CREATE NONCLUSTERED INDEX [IX_Marker_SubID] ON [Cache].[Marker] 
(
    [SubID] ASC
)
INCLUDE ( [EquipmentID],[ReadTime]) 

次のクエリを実行しています。

Declare @EquipmentId varchar(50)

SELECT TOP 1 
    C44DistId,
    C471DistId,
    C473RightLotId
From Cache.vwMarker m
    INNER JOIN Cache.vwCoaterRecipe AS cr ON cr.MarkerId = m.ID AND M.EquipmentID = @EquipmentId
Order By m.Id Desc

クエリ プランは次のようになります。

ここに画像の説明を入力

Marker テーブルには約 700 万行あるため、スキャンにはかなりの負荷がかかります。7M 行には 24 個の一意の EquipmentId 値しかないため、スキャンが実行されている可能性があります。

サーバーの負荷によっては、このクエリの実行に 40 秒以上かかることがよくあります。SQL Server に Marker テーブルでシークを実行させる方法を (ある種のインデックスを作成することによって) 考えてみました。私は何も思いつくことができませんでした。仕方がないのかもしれませんが、まずは聞いてみようと思いました。

4

1 に答える 1

1

と列の両方をMarker含むテーブル上の唯一のインデックスは。です。このインデックスは最初の列として含まれていないため、検索することはできません。インデックスを逆の順序でスキャンして、一致する最初のエントリを見つける必要があります。EquipmentIDIdIX_Marker_IdEquipmentIDEquipmentID

このようなものが役立つかもしれません:

CREATE NONCLUSTERED INDEX [IX_Marker_EquipmentID_Id] ON [Cache].[Marker] 
(
   [EquipmentID] ASC,
   [ID] DESC
)

編集:もちろん、クラスター化インデックスには両方の列が含まれますが、24の異なるEquipmentID値しかないため、最大値を見つけるには290000行以上をスキャンする必要がありますId。インデックスを逆にスキャンするIX_Marker_Idことで、一致するものが見つかるとすぐに停止できEquipmentIDます。これはおそらく高速です。

于 2013-03-20T19:57:44.057 に答える