在下面的示例中,什么是内存分数以及如何摆脱它们(或排序运算符)?

Mar*_*lli 5 performance sql-server optimization execution-plan query-performance performance-tuning

此执行计划具有以下内存部分: Memory fraction input:1, Memory Fraction Output:1.

这是一个非常简单的查询:

SELECT                  [a].[activityId],
                        [a].[title],
                        [a].[description],
                        [a].[inclusions],
                        [d].[path],
                        [d].[uploadToBucket],
                        [a].[imageUriMain],
                        [a].[locationId]
FROM                    [dbo].[activity]                AS a
LEFT JOIN               [dbo].[document]                AS d 
       ON d.documentId = a.documentId 
      AND d.activityId = a.activityId

ORDER BY                title                           ASC
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,什么是内存分数以及如何摆脱它们(或排序运算符)?

Mar*_*lli 5

查看排序运算符的属性:它具有MemoryFractions Input="1" Output="1"

在此处输入图片说明

摆脱这种排序操作

在看看索引和表的定义dbo.activity 有没有nonclustered indexes只有主键

CREATE TABLE [dbo].[activity] ( 
[activityId]      INT              IDENTITY(1,1)                 NOT NULL,
[title]           VARCHAR(100)                     NOT NULL,
[description]     VARCHAR(max)                     NOT NULL,
[inclusions]      VARCHAR(max)                         NULL,
[imageUriMain]    VARCHAR(255)                         NULL,
[imageUriThumb]   VARCHAR(255)                         NULL,
[imageUriTeaser]  VARCHAR(255)                         NULL,
[categoryId]      INT                              NOT NULL  CONSTRAINT [DF__activity__catego__0F975522] DEFAULT ((1)),
[locationId]      INT                                  NULL,
[documentId]      INT                                  NULL,
CONSTRAINT   [PK_activity]  PRIMARY KEY CLUSTERED    ([activityId] asc),
CONSTRAINT   [FK_activity_category]                         FOREIGN KEY ([categoryId]) REFERENCES [ref_activityCategory]([categoryId]),
CONSTRAINT   [FK_activity_location]                         FOREIGN KEY ([locationId]) REFERENCES [location]([locationId]))

GO
Run Code Online (Sandbox Code Playgroud)

与表相同 documents

CREATE TABLE [dbo].[document] ( 
[documentId]      INT              IDENTITY(1,1)                 NOT NULL,
[uploadToBucket]  VARCHAR(200)                         NULL,
[path]            VARCHAR(200)                         NULL,
[activityId]      INT                                  NULL,
CONSTRAINT   [PK__document__EFAAAD856EBBBDCD]  PRIMARY KEY CLUSTERED    ([documentId] asc))
Run Code Online (Sandbox Code Playgroud)

我创建了以下索引(注意order by此查询所需的列和所有列):

create index I_title_01 on [dbo].[activity] 
(title asc,documentId  asc,activityid asc)
INCLUDE(
        [description],
        [inclusions],
        [imageUriMain],
        [locationId]
)
WITH (  PAD_INDEX = OFF, FILLFACTOR = 100  , 
SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF, 
STATISTICS_NORECOMPUTE = OFF, ONLINE = OFF, --drop_existing=on,
DATA_COMPRESSION=page, ALLOW_ROW_LOCKS = ON, 
ALLOW_PAGE_LOCKS = ON ) ON NONCLUSTERED_INDEXES


create index I_doc_01 on [dbo].[document] 
(documentId  asc,activityid asc)
INCLUDE(
                            [path],
                            [uploadToBucket]
)
WITH (  PAD_INDEX = OFF, FILLFACTOR = 100  , 
SORT_IN_TEMPDB = OFF , IGNORE_DUP_KEY = OFF, 
STATISTICS_NORECOMPUTE = OFF, ONLINE = OFF, 
 --drop_existing=on,
DATA_COMPRESSION=page, ALLOW_ROW_LOCKS = ON, 
ALLOW_PAGE_LOCKS = ON ) ON NONCLUSTERED_INDEXES
Run Code Online (Sandbox Code Playgroud)

现在新的执行计划看起来像这样(没有sort operation):

在此处输入图片说明

关于什么是内存分数,我从下面的这个站点得到了我的答案,它有解释甚至例子:

批处理模式内存分数

关于内存分数的信息很少。我将它们定义为查询计划中的信息,可以为您提供有关每个运算符在总查询内存授予中所占份额的线索。对于插入到带有列存储索引的表中的查询计划来说,这自然更复杂,但这里不会介绍。大多数参考资料会告诉您不要担心内存碎片,或者它们在大多数情况下没有用。在我调整过的数千个查询中,我只能想到几个与内存分数相关的查询。有时,即使 SQL Server 报告大量查询内存未使用,查询也会溢出到 tempdb。在这些情况下,我通常希望基数估计不佳,这会导致内存分数对于溢出运算符来说太低。