Sql-Server

在下面的範例中,什麼是記憶體分數以及如何擺脫它們(或排序運算符)?

  • September 18, 2018

此執行計劃具有以下記憶體部分: 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

在上面的範例中,什麼是記憶體分數以及如何擺脫它們(或排序運算符)?

查看排序運算符的屬性:它有MemoryFractions Input=“1” Output=“1”

在此處輸入圖像描述

擺脫這種排序操作

看看表的索引和定義,不僅dbo.activitynonclustered 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

與表相同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))

我創建了以下索引(注意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

現在新的執行計劃看起來像這樣(沒有sort operation):

在此處輸入圖像描述

關於什麼是記憶體分數,我從下面的這個網站得到我的答案,它有解釋甚至是例子:

批處理模式記憶體分數

關於記憶體分數的資訊很少。我會將它們定義為查詢計劃中的資訊,它可以為您提供有關每個操作員在總查詢記憶體授權中所佔份額的線索。對於插入具有列儲存索引的表的查詢計劃,這自然會更加複雜,但這裡不會涉及。大多數參考資料會告訴您不要擔心記憶體分數,或者它們大部分時間都沒有用。在我調整的數千個查詢中,我只能想到一些與記憶體分數相關的查詢。即使 SQL Server 報告大量查詢記憶體未使用,有時查詢也會溢出到 tempdb。在這些情況下,我通常希望基數估計差,這會導致記憶體分數對於溢出運算符來說太低。

引用自:https://dba.stackexchange.com/questions/217959