1

非常に多くの論理読み取りを引き起こしているように見える CTE クエリがあります (またはそうでない可能性があります)。SQL Server プロファイラー トレースを実行しましたが、このクエリは、実行時間の最も長いクエリの 1 つを一貫して引き起こしているようです。(ページがヒットするたびに呼び出されます)

基本的に、CTE が正しく最適化されているか、または改善できるかどうかを知りたいです。

SET STATISTICS IO ON;
GO
    ;WITH cte (PageId, PageTitle, PageType, PageHeadingId, ParentPage, InNavigation, OrgLevel, SortKey, PageOrder, PathLength, PathName, Active) AS
     (
      SELECT
        PageId, 
        PageTitle,
        PageType,
        PageHeadingId,
        ParentPage, 
        InNavigation,
        0, 
        CAST (PageOrder  AS VARBINARY(200)), 
        PageOrder, 
        0 AS PathLength, 
        CAST('' as varchar(300)) AS PathName,
        Active
       FROM dbo.ContentPage
       WHERE ParentPage = 0
        AND InNavigation = 1
      UNION ALL
      SELECT
        b.PageId, 
        b.PageTitle, 
        b.PageType,
        b.PageHeadingId,
        b.ParentPage,
        b.InNavigation, 
        cte.OrgLevel+1,
        CAST(cte.SortKey + CAST (b.PageOrder AS BINARY(4)) AS VARBINARY(200)),
        b.PageOrder, 
        ((cte.OrgLevel+1) + len('....'+b.PageTitle)) as PathLength,
        CAST ((cte.PathName+'....') AS VARCHAR(300)) AS PathName,
        b.Active
       FROM dbo.ContentPage b
         JOIN cte ON b.ParentPage = cte.PageId
       WHERE b.PageType NOT IN (4, 8, 11, 12, 14)
        -- Remove specific page types from the ContentPage table
     )
    SELECT *, (PathName+PageTitle) AS Hierarchy 
    FROM cte WHERE InNavigation = 1     
    ORDER BY SortKey--, PageOrder
SET STATISTICS IO OFF;
GO

この行を離れると:

WHERE b.PageType NOT IN (4, 8, 11, 12, 14)

アウトすると、論理読み取りの数が ~8500 から ~13000 に跳ね上がります。

(クエリが行うことは、ASP.NET でドロップダウン メニュー階層を構築することです) 論理読み取りが問題ない場合は、このメニューをキャッシュ/保存する別の方法を考え出す必要があると思います (更新される 2 または週3回)

ありがとう

ContentPage のテーブル構造

CREATE TABLE [dbo].[ContentPage](
    [PageId] [int] IDENTITY(1,1) NOT NULL,
    [PageTitle] [nvarchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [PageQuote] [nvarchar](400) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [MetaKeywords] [nvarchar](200) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [MetaDescription] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [PageContent] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [Active] [bit] NOT NULL CONSTRAINT [DF_ContentPage_Active]  DEFAULT ((0)),
    [InNavigation] [bit] NOT NULL CONSTRAINT [DF_ContentPage_InNavigation]  DEFAULT ((1)),
    [PageOrder] [int] NOT NULL CONSTRAINT [DF_ContentPage_PageOrder]  DEFAULT ((50)),
    [ParentPage] [int] NOT NULL CONSTRAINT [DF_ContentPage_ParentPage]  DEFAULT ((0)),
    [PageType] [int] NOT NULL CONSTRAINT [DF_ContentPage_PageType]  DEFAULT ((1)),
    [CreatedBy] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [CreatedOn] [datetime] NULL,
    [ModifiedBy] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [ModifiedOn] [datetime] NULL,
    [PageViews] [int] NOT NULL CONSTRAINT [DF_ContentPage_PageViews]  DEFAULT ((0)),
    [Emailed] [int] NOT NULL CONSTRAINT [DF_ContentPage_Emailed]  DEFAULT ((0)),
    [Emailable] [bit] NOT NULL CONSTRAINT [DF_ContentPage_Emailable]  DEFAULT ((1)),
    [Printable] [bit] NOT NULL CONSTRAINT [DF_ContentPage_Printable]  DEFAULT ((1)),
    [ContactButton] [bit] NOT NULL CONSTRAINT [DF_ContentPage_PDFable]  DEFAULT ((0)),
    [PageHeadingId] [int] NULL CONSTRAINT [DF_ContentPage_PadeHeadingId]  DEFAULT ((0)),
    [AlternativeTitle] [nvarchar](150) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [RighthandImage] [nvarchar](250) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [IsMicrosite] [bit] NOT NULL CONSTRAINT [DF_ContentPage_IsMicrosite]  DEFAULT ((0)),
 CONSTRAINT [PK_ContentPage] PRIMARY KEY CLUSTERED 
(
    [PageId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
4

1 に答える 1

0

CTE は内部 JOIN を使用してそれ自体に戻します。したがって、ここには一種の外部キー関係があります。

FROM dbo.ContentPage b
JOIN cte ON b.ParentPage = cte.PageId

したがって、インデックスをオンにb.ParentPageして別のインデックスをオンにPageIdすると役立つ場合があります。

また、クエリにはとのWHERE句があるため、 のインデックス(または組み合わせたもの) を検討する必要があります。b.PageTypeInNavigationPageType(PageType, InNavigation)

SortKeyさらに、どれが基づいているかでソートしてPageOrderいるため、そのインデックスも役立つ場合があります。

一度に 1 つのインデックスを作成し、クエリを再実行して、統計と数値を比較し、どれが本当にメリットがあるか (そしてどれがメリットがないか) を判断してください。インデックス作成は正確な科学ではありません。何が役に立ち、何が役に立たないかを常に予測できるわけではありません。試して元のクエリと比較し、何が役に立ち、何が役に立たないかを判断する必要があります。

于 2011-12-12T12:07:17.830 に答える