3

我在生产服务器中部署了 Orchard 1.8。生产服务器是具有非常好的规格的专用服务器。然而,每个页面的加载时间约为 3 到 4 秒,这在我们的标准中非常慢。我们拥有超过一百万个内容项目,我们的印象是 Orchard 能够处理这样的负载。即使加载空主页也需要花费这么多时间。所以我安装了 MiniProfiler 模块并设法查明瓶颈。它来自这个 SQL 查询

DECLARE @p0 NVARCHAR(4000) = N'Layer'
        ,@p1 BIT = 1;

SELECT this_.Id AS Id1795_2_
        ,this_.Number AS Number1795_2_
        ,this_.Published AS Published1795_2_
        ,this_.Latest AS Latest1795_2_
        ,this_.Data AS Data1795_2_
        ,this_.ContentItemRecord_id AS ContentI6_1795_2_
        ,contentite1_.Id AS Id1794_0_
        ,contentite1_.Data AS Data1794_0_
        ,contentite1_.ContentType_id AS ContentT3_1794_0_
        ,contenttyp2_.Id AS Id1796_1_
        ,contenttyp2_.NAME AS Name1796_1_
FROM Orchard_Framework_ContentItemVersionRecord this_
INNER JOIN Orchard_Framework_ContentItemRecord contentite1_ ON this_.ContentItemRecord_id = contentite1_.Id
INNER JOIN Orchard_Framework_ContentTypeRecord contenttyp2_ ON contentite1_.ContentType_id = contenttyp2_.Id
WHERE contenttyp2_.NAME = @p0
        AND this_.Published = @p1

我为表Orchard_Framework_ContentTypeRecordName列 ASC)和表Orchard_Framework_ContentItemVersionRecordPublished列 DESC)添加了索引,但没有提高脚本执行时间。

如何缓解这个瓶颈?这真的是一个交易破坏者,我们花了几个月的时间为一个需要我们注入一百万个内容项目的客户定制这个网站。如果这种情况无法补救,我们将把整个项目都刮掉。请帮忙。

编辑
我通过在我的生产服务器和我的开发机器上部署 Orchard 1.8.1 的新实例进行了测试。然后用完全相同的一百万个内容项抽取两个实例。接下来,我在服务器和开发机器上使用 SQL Server Management Studio 执行了上面的 SQL 脚本。我的生产服务器用了 2 秒多的时间来检索结果,而我的开发机器用了不到 1 秒的时间来检索完全相同的结果。

这很奇怪,因为我的生产服务器比我的开发机器强大得多。服务器是只运行该 Orchard 实例的专用精益机器,而我的开发机器除了运行 Orchard 实例外,还打开了 Visual Studio 2013 和 20++ 浏览器选项卡。我的服务器有 16GB 的 RAM,而我的开发机器只有 6GB,内存使用率高达 96%。服务器正在运行带有 SQL Server 2014 企业版的 Windows Server 2012,而我的开发机器正在运行带有 SQL Server 2012 Express Edition 的 Windows 7。两台机器的 SQL 语句执行计划也不同。我不是很精通阅读执行计划,但如果有必要,我可以在此处包含 xml 版本的执行计划。

更新
最后,我能够确定问题出在 SQL Server 上。在执行上述脚本时,SQL Server 2014 查询优化器生成的执行计划与 SQL Server 2012 相比不是最优的。所以我现在的策略是强制 SQL Server 2014(生产服务器)使用 SQL Server 2012 的执行计划(开发机器)。

这确实是 SQL Server 而不是 Orchard 的问题,但由于我已经创建了这个问题,所以我不妨分享我的尝试。我使用 SQL Server 2012 中的执行计划在 SQL Server 2014 中以临时方式查询上述脚本。

DECLARE @p0 NVARCHAR(4000) = N'Layer'
        ,@p1 BIT = 1;

SELECT this_.Id AS Id1795_2_
        ,this_.Number AS Number1795_2_
        ,this_.Published AS Published1795_2_
        ,this_.Latest AS Latest1795_2_
        ,this_.Data AS Data1795_2_
        ,this_.ContentItemRecord_id AS ContentI6_1795_2_
        ,contentite1_.Id AS Id1794_0_
        ,contentite1_.Data AS Data1794_0_
        ,contentite1_.ContentType_id AS ContentT3_1794_0_
        ,contenttyp2_.Id AS Id1796_1_
        ,contenttyp2_.NAME AS Name1796_1_
FROM Orchard_Framework_ContentItemVersionRecord this_
INNER JOIN Orchard_Framework_ContentItemRecord contentite1_ ON this_.ContentItemRecord_id = contentite1_.Id
INNER JOIN Orchard_Framework_ContentTypeRecord contenttyp2_ ON contentite1_.ContentType_id = contenttyp2_.Id
WHERE contenttyp2_.NAME = @p0
        AND this_.Published = @p1
OPTION (USE PLAN N'<ShowPlanXML ..... (Execution Plan here)')

查询用了不到一秒的时间执行,这是所需的结果。现在,我不能把这个执行计划放在 Orchard 核心源代码中,可以吗?所以我必须在 SQL Server 2014 中创建一个计划指南并包含这个执行计划。这就是我所做的

EXEC sp_create_plan_guide 
@name = N'Published_Layer_Content_Type',
@stmt = N'SELECT this_.Id AS Id1795_2_
        ,this_.Number AS Number1795_2_
        ,this_.Published AS Published1795_2_
        ,this_.Latest AS Latest1795_2_
        ,this_.Data AS Data1795_2_
        ,this_.ContentItemRecord_id AS ContentI6_1795_2_
        ,contentite1_.Id AS Id1794_0_
        ,contentite1_.Data AS Data1794_0_
        ,contentite1_.ContentType_id AS ContentT3_1794_0_
        ,contenttyp2_.Id AS Id1796_1_
        ,contenttyp2_.NAME AS Name1796_1_
FROM Orchard_Framework_ContentItemVersionRecord this_
INNER JOIN Orchard_Framework_ContentItemRecord contentite1_ ON this_.ContentItemRecord_id = contentite1_.Id
INNER JOIN Orchard_Framework_ContentTypeRecord contenttyp2_ ON contentite1_.ContentType_id = contenttyp2_.Id
WHERE contenttyp2_.NAME = @p0
        AND this_.Published = @p1',
@type = N'SQL',
@module_or_batch = NULL,
@params = N'@p0 NVARCHAR(4000), @p1 BIT',
@hints = N'OPTION (USE PLAN N''[Execution Plan here. All single quotes are escaped accordingly]'')'

计划指南已成功创建。我已经验证了使用SELECT * FROM sys.plan_guides. 但是,每当我执行查询时,都没有使用执行计划。出了什么问题?我是否错误地创建了计划指南?

4

0 回答 0