我有一个CTE查询,似乎引起了大量的逻辑读取(或者可能不是)。 我已经运行了SQL Server Profiler跟踪,并且此查询似乎一直导致运行时间最长的查询之一。 (每次点击时都会调用)

基本上,我想知道我的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]

===============>>#1 票数:0 已采纳

您的CTE使用内部的JOIN本身-因此这里存在某种外键关系:

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

因此,在b.ParentPage上有一个索引,在PageId上有另一个索引可能会有所帮助。

同样,您的查询在b.PageTypeInNavigation上具有WHERE子句,因此您应考虑在PageTypePageType索引(或可能将(PageType, InNavigation)组合在一起)。

此外,你通过排序SortKey这是基于PageOrder等等,一个指数也可能是有用的。

尝试一次创建一个索引,重新运行查询,比较统计数据和数字-然后确定哪些确实对您有利(哪些没有)。 索引并不是一门精确的科学-您不能总是预测出什么有帮助和有用,什么没有用-您必须尝试一下并将其与原始查询进行比较,然后再确定有帮助和无用。

  ask by kolin translate from so

未解决问题?本站智能推荐:

2回复

在SQL Server 2005中使用CTE为数字添加空值

我有一些数据如下 期望的输出 输出是什么,对于数字,它被那些许多空值替换。 例如,数值为2,它将是2个空值。 ddl如下 请提供基于CTE的解决方案。 我已经有了程序上的方法,但是我需要对基于CTE的解决方案有所了解。 我目前使用的解决方案 调用方
4回复

如何在CTE之后使用if语句(SQL Server 2005)

昨晚我写的是一个简单的T-SQL程序 我在编译后发现它抛出的错误类似于“如果附近有错误的语句” 怎么了? 但是,我通过使用其他方式做到了这一点。 但我想知道为什么它不起作用!
3回复

SQL Server 2005-CTE,保留值并插入数据集中

可以说您有一个这样的表(SQL SERVER 2005) 您拥有返回此数据集的CTE: 您如何保存初始子ID,以便获取此结果集: 所以基本上我在做的是保留原始的孩子id并返回它而不是其他... 到目前为止,这是CTE查询,效果很好:
1回复

在SQL Server 2005中评估CTE

我有一个关于MS SQL如何评估CTE内部函数的问题。 几次搜索没有发现与此问题相关的任何结果,但我很抱歉,如果这是常识,我只是落后于曲线。 这不是第一次:-) 这个查询是我实际做的简化(显然是动态性较小)的版本,但它确实表现出我遇到的问题。 它看起来像这样: 关于上述所有执
1回复

稳定的SQL Server存储过程性能异常下降

我在SQL Server 2005中遇到一个非常奇怪的问题。 昨天,用户报告了我们数据库应用程序特定部分的运行缓慢。 我不确定缓慢的普遍程度-绝对不是到处都在,因为这是报告的系统的唯一部分-但我隔离了相关的存储过程,该过程以前需要2-3秒才能运行,现在一直可以50- 60秒 这是一
4回复

SQL 2005 CTE与TEMP表在其他表的连接中使用时的性能

我有一个复杂的查询,我需要在后续查询(实际更新语句)中使用。 我尝试过使用CTE和临时表。 使用CTE的性能与临时表方法相比非常糟糕。 它像15秒对毫秒。 为了简化测试而不是在后续查询中加入CTE / Temp表,我只是从中选择了*。 在那种情况下,他们执行相同的操作 我已经查看
2回复

如何为具有多个父项的子项创建SQL Server 2005 CTE以返回父子记录

我正在尝试使用SQL Server中的CTE但是已经达到了一个死胡同,让下面的场景工作。 我有一个类似于这个的层次结构表: 预期成绩: 所以基本上我们有一个父子层次表,有一个细微的区别。 每个孩子可能有一个以上的父母。 我已经研究了许多关于创建返回父子记录的CTE的博客文章
2回复

CTE内部的SQL Server视图导致性能不佳

当我在CTE中使用视图时,引用CTE的每个子查询似乎都会重新查询视图。 每个子查询都会重复执行计划的大块。 从表中选择时不是这种情况。 这是预期的吗? 有没有办法绕过它? 我正在使用SQL Server 2005 编辑: 我正在尝试使用下面的查询从页面中的视图中获取数
1回复

使用SQL Server CTE返回所有父记录

我有以下表类层次结构。 我希望得到以下结果。 我计划通过加入我的特征表来使用这些结果来获得继承的特征。 在过去,我使用循环来正确设置数据,但我想使用CTE来获得这些结果。 这是我到目前为止所尝试的。 我从中获得的结果只是沿着层次结构向下走,以获得完整的列表。 我
2回复

我们如何在sql server中的子查询中使用CTE?

我们如何在sql server中的子查询中使用CTE? 喜欢 .. 选择id(我想在这里使用CTE),来自table_name的名称