2

这是我的查询:

exec sp_executesql N'set arithabort off;set statistics time on; set transaction isolation level read uncommitted;With cte as (Select peta_rn = ROW_NUMBER() OVER (ORDER BY  d.LastStatusChangedDateTime  desc )  
                                                , d.DocumentID,
                                                d.IsReEfiled, d.IGroupID, d.ITypeID, d.RecordingDateTime, d.CreatedByAccountID, d.JurisdictionID, 
                                                d.LastStatusChangedDateTime as LastStatusChangedDateTime
                                                ,  d.IDate, d.InstrumentID, d.DocumentStatusID
                                                , u.Username
                                                , it.Abbreviation AS ITypeAbbreviation
                                                , ig.Abbreviation AS IGroupAbbreviation,
                                                d.DocumentDate                                               
                                From Documents d                             
                                Inner Join ITypes it  on it.ITypeID = d.ITypeID
                                 Inner Join Users u on d.UserID = u.UserID Inner Join IGroupes ig on ig.IGroupID = d.IGroupID
                                Where 1=1  And  (  d.DocumentStatusID = 9  ) ) Select cte.DocumentID, 
                                cte.IsReEfiled, cte.IGroupID, cte.ITypeID, cte.RecordingDateTime, cte.CreatedByAccountID, cte.JurisdictionID, 
                        cte.LastStatusChangedDateTime as LastStatusChangedDateTime
                        ,  cte.IDate, cte.InstrumentID, cte.DocumentStatusID,cte.IGroupAbbreviation, cte.Username, j.JDAbbreviation, inf.DocumentName,
                       cte.ITypeAbbreviation, cte.DocumentDate, ds.Abbreviation as DocumentStatusAbbreviation,  ds.Name as DocumentStatusName,
                        ( SELECT CAST(CASE WHEN cte.DocumentID = (
                                SELECT TOP 1 doc.DocumentID
                                FROM  Documents doc
                                WHERE doc.JurisdictionID = cte.JurisdictionID
                                        AND doc.DocumentStatusID = cte.DocumentStatusID
                                ORDER BY LastStatusChangedDateTime) 
                            THEN 1
                            ELSE 0
                        END AS BIT)
                        ) AS CanChangeStatus ,

                        Upper((Select Top 1 Stuff( (Select ''='' + dbo.GetDocumentNameFromParamsWithPartyType(Business, FirstName, MiddleName, LastName, t.Abbreviation, NameTypeID, pt.Abbreviation, IsGrantor, IsGrantee)  From DocumentNames dn
                                Left Join Titles t
                                    on dn.TitleID = t.TitleID               
                                Left Join PartyTypes pt
                                    On pt.PartyTypeID = dn.PartyTypeID
                                        Where DocumentID = cte.DocumentID
                                            For XML PATH('''')),1,1,''''))) as FlatDocumentName, (SELECT COUNT(*) FROM CTE) AS TotalRecords

                        FROM cte Left Join DocumentStatuses ds On
                        cte.DocumentStatusID = ds.DocumentStatusID Left Join InstrumentFiles inf On cte.DocumentID = inf.DocumentID 
                    Left Join Jurisdictions j on j.JurisdictionID = cte.JurisdictionID Where 1=1 And 
                    peta_rn>@7 AND peta_rn<=@8 Order by peta_rn set statistics time off; ',N'@0 int,@1 int,@2 int,@3 int,@4 int,@5 int,@6 int,@7 int,@8 int',
                    @0=1,@1=5,@2=9,@3=1,@4=5,@5=9,@6=1,@7=97500,@8=97550

这是我的 IGroupes 表定义:

CREATE TABLE [dbo].[IGroupes](
    [IGroupID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [varchar](64) NOT NULL,
    [JurisdictionID] [int] NOT NULL,
    [Abbreviation] [varchar](12) NOT NULL,
 CONSTRAINT [PK_IGroupes] PRIMARY KEY NONCLUSTERED 
(
    [IGroupID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

SET ANSI_PADDING ON

GO

/****** Object:  Index [IX_IGroupes_Abbreviation]    Script Date: 10/11/2013 4:21:46 AM ******/
CREATE NONCLUSTERED INDEX [IX_IGroupes_Abbreviation] ON [dbo].[IGroupes]
(
    [Abbreviation] ASC
)
INCLUDE (   [IGroupID],
    [Name],
    [JurisdictionID]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO

SET ANSI_PADDING ON

GO

/****** Object:  Index [IX_IGroupes_JurisdictionID]    Script Date: 10/11/2013 4:21:46 AM ******/
CREATE NONCLUSTERED INDEX [IX_IGroupes_JurisdictionID] ON [dbo].[IGroupes]
(
    [JurisdictionID] ASC
)
INCLUDE (   [IGroupID],
    [Name],
    [Abbreviation]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO

SET ANSI_PADDING ON

GO

/****** Object:  Index [IX_IGroupes_Name]    Script Date: 10/11/2013 4:21:46 AM ******/
CREATE NONCLUSTERED INDEX [IX_IGroupes_Name] ON [dbo].[IGroupes]
(
    [Name] ASC
)
INCLUDE (   [IGroupID],
    [JurisdictionID],
    [Abbreviation]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
GO

但是请看它正在使用表扫描。这个手术太费我了。IGroupes表只有 7 行,Documents表有大约 98K 记录。然而,当我加入时,d.IGroupID = ig.IGroupID它显示实际行数超过 600K!那就是问题所在。请参阅随附的屏幕截图:

在此处输入图像描述

如果有人对完整的查询计划 xml 感兴趣,这里是:

https://www.dropbox.com/s/kldx24x3j8vndpe/plan.xml

任何帮助表示赞赏。谢谢!

4

2 回答 2

2

您拥有的 3 个索引(PK 除外)IGroupes都不会帮助此查询,因为您没有在 where 或 join 子句中使用这些字段中的任何一个。除非您需要这些索引来进行其他查询,否则我会删除它们。他们只是要给查询优化器更多的选择来测试(和拒绝)。

主键上的索引PK_IGroupes应该是聚集的。这将允许它进行索引查找(或书签查找)。如果由于某些其他原因无法对其进行聚类,请尝试在IGroupIDandAbbreviation上按该顺序创建索引(或包括Abbreviation现有 PK 索引中的列)。

如果它仍然没有选择正确的索引,您可以使用诸如WITH(INDEX(0))or之类的提示WITH(INDEX('index-name'))

600k 行确实来自这样一个事实,即它对 98k 行乘以 7 行进行嵌套循环连接。如果上面的索引不起作用,您可以尝试将 替换INNER JOIN iGroupesINNER HASH JOIN IGroupes

于 2013-10-11T16:12:03.370 回答
2

在这种情况下,表扫描可能比使用表上的任何索引更有效IGroupes。如果您认为表扫描操作是此查询中的瓶颈(尽管我不确定它是 3% 的成本),您可以尝试修改PK_IGroupes为聚集索引,或者您可以尝试像这样的索引

CREATE UNIQUE NONCLUSTERED INDEX [IX_IGroupes_IGroupID]
    ON [dbo].[IGroupes] ([IGroupID]) INCLUDE ([Abbreviation])
于 2013-10-11T09:43:24.757 回答