0

我有一个选择查询的性能问题。查询可能需要超过 4 分钟,这太长了。此查询在 .Net 客户端进程上启动,但不在 Microsoft SQLServer Management Studio 上启动。所以它有时可以做 5 秒,有时可以做 4 分钟、1 分钟、30 秒。所以我有3个问题:

  1. 为什么这个选择查询太长了?因为它可以在 5 秒内释放 sqlserver 缓存。我使用指令 DBCC FREEPROCCACHE 和 DBCC DROPCLEANBUFFERS 测试此查询

  2. 为什么一个名为 sort_init 的 sqlserver 系统 SQLTransaction 重建索引大约需要 30 秒?我怎样才能继续减少这个时间?

  3. 为什么在执行计划上,我有 Clustered Index Scan,而不是 Clustered Index Seek(扫描所有页面可能需要很长时间)。扫描的每个聚集索引都是每个表的主键。注意:我还有很多使用这些表的查询,这些表在连接子句中有聚集索引搜索。我做错了什么?我怎样才能让查询运行得更快?如何优化索引?

我使用 SQL Profiler 来跟踪问题,所以我有以下主要事件:

A) SQL 探查器:

  • SP:Stmt已完成:

文本数据:

`SELECT [DespatchNote].[Id], [DespatchNote].[RealType], [DespatchNote].[DbOwner], [DespatchNote].[Archived], [CreatedOn], [CreatedById], [UpdatedOn], [UpdatedById], [KeyingFinished], [IsValidated], [ValidatedOn], [ValidatedById], [Notes], [DefaultDisplayLanguageId], [ReferencedTransactionId], [TransactionNumber], [IsCanceled], [CanceledOn], [CanceledById], [TransactionType], [IsPending], [IsGenerated], [PrintCount], [LastPrintDate], [AttachedFile], [IsPointOfSalesTransaction], [IsAffiliatedTransaction], [IsDone], [DoneById], [DoneOn], [IsSent], [SentOn] FROM [DespatchNote] INNER JOIN [Flow] ON [DespatchNote].[Id] = [Flow].[Id] INNER JOIN [Transaction] ON [DespatchNote].[Id] = [Transaction].[Id] INNER JOIN [ProductsMovements] ON [DespatchNote].[Id] = [ProductsMovements].[Id] WHERE (([DespatchNote].[RealType] = @param42485) AND (([ProductsMovements].[IsDone] = @param42486) AND ([DespatchNote].[Archived] IS NULL)))`
  • 持续时间(毫秒)

    : 201277

  • SQL事务:

ObjectName:sort_init
持续时间(毫秒):29982
EventSubClass:1-Commit

B) 使用 SHOWPLAN_ALL 进行查询

SELECT [DespatchNote].[Id], [DespatchNote].[RealType], [DespatchNote].[DbOwner], [DespatchNote].[Archived],   [CreatedOn], [CreatedById], [UpdatedOn], [UpdatedById], [KeyingFinished], [IsValidated], [ValidatedOn],    [ValidatedById], [Notes], [DefaultDisplayLanguageId], [ReferencedTransactionId], [TransactionNumber],    [IsCanceled], [CanceledOn], [CanceledById], [TransactionType], [IsPending], [IsGenerated],    [PrintCount], [LastPrintDate], [AttachedFile], [IsPointOfSalesTransaction], [IsAffiliatedTransaction],    [IsDone], [DoneById], [DoneOn], [IsSent], [SentOn]    FROM [DespatchNote]     INNER JOIN [Flow] ON [DespatchNote].[Id] = [Flow].[Id]     INNER JOIN [Transaction] ON [DespatchNote].[Id] = [Transaction].[Id]     INNER JOIN [ProductsMovements] ON [DespatchNote].[Id] = [ProductsMovements].[Id]     WHERE (([DespatchNote].[RealType] = (select top 1 DespatchNote.RealType from DespatchNote))     AND (([ProductsMovements].[IsDone] = 1)      AND ([DespatchNote].[Archived] IS NULL)))
  |--Merge Join(Inner Join, MERGE:([x3distributor].[dbo].[Flow].[Id])=([x3distributor].[dbo].[ProductsMovements].[Id]), RESIDUAL:([x3distributor].[dbo].[Flow].[Id]=[x3distributor].[dbo].[ProductsMovements].[Id]))
       |--Clustered Index Scan(OBJECT:([x3distributor].[dbo].[Flow].[PK_Flow]), ORDERED FORWARD)
       |--Merge Join(Inner Join, MERGE:([x3distributor].[dbo].[ProductsMovements].[Id])=([x3distributor].[dbo].[Transaction].[Id]), RESIDUAL:([x3distributor].[dbo].[Transaction].[Id]=[x3distributor].[dbo].[ProductsMovements].[Id]))
            |--Nested Loops(Inner Join, WHERE:([x3distributor].[dbo].[DespatchNote].[RealType]=[x3distributor].[dbo].[DespatchNote].[RealType]))
            |    |--Top(TOP EXPRESSION:((1)))
            |    |    |--Index Scan(OBJECT:([x3distributor].[dbo].[DespatchNote].[IX3_DespatchNote_RealType]))
            |    |--Merge Join(Inner Join, MERGE:([x3distributor].[dbo].[DespatchNote].[Id])=([x3distributor].[dbo].[ProductsMovements].[Id]), RESIDUAL:([x3distributor].[dbo].[DespatchNote].[Id]=[x3distributor].[dbo].[ProductsMovements].[Id]))
            |         |--Clustered Index Scan(OBJECT:([x3distributor].[dbo].[DespatchNote].[PK_DespatchNote]),  WHERE:([x3distributor].[dbo].[DespatchNote].[Archived] IS NULL) ORDERED FORWARD)
            |         |--Clustered Index Scan(OBJECT:([x3distributor].[dbo].[ProductsMovements].[PK_ProductsMovements]),  WHERE:([x3distributor].[dbo].[ProductsMovements].[IsDone]=(1)) ORDERED FORWARD)
            |--Clustered Index Scan(OBJECT:([x3distributor].[dbo].[Transaction].[PK_Transaction]), ORDERED FORWARD)

C) 对于每个表,我启动 DBCC SHOWCONTIG([MyTable]),所以:

DBCC SHOWCONTIG 分析 la table 'Transaction'...

表:“交易”(770101784);索引 ID : 1, base de données ID : 5 分析 du niveau TABLE effectuée。- 页面分析......................................:3690 - 扩展分析...... .....................: 466 - Commutateurs d'extension....................... ........: 526 - Moyenne des pages par extension.......................: 7.9 - Densité d'analysis [meilleure valeur: valeur réelle].......: 87.67% [462:527] - Fragmentation d'analyze logique.......: 1.95% - Fragmentation d'analysis d'extension.......................:5.79% - Moyenne d'octets libres par page........ .....:631.1 - Densité de page moyenne(完整)......................:92.20%

DBCC SHOWCONTIG 分析 la table 'DespatchNote'...

表:'DespatchNote'(1138103095);索引 ID : 1, base de données ID : 5 分析 du niveau TABLE effectuée。- 页面分析......................................:409 - 扩展分析...... .....................: 52 - Commutateurs d'extension....................... .......: 51 - Moyenne des pages par extension.......................: 7.9 - Densité d'analysis [meilleure valeur: valeur réelle].......: 100.00% [52:52] - Fragmentation d'analyze logique........: 0.00% - Fragmentation d'analysis d'extension.......................:5.77% - Moyenne d'octets libres par page........ .....:806.2 - Densité de page moyenne(完成)......................:90.04%

DBCC SHOWCONTIG 分析 la 表 'ProductsMovements'...

表:'ProductsMovements'(1074102867);索引 ID : 1, base de données ID : 5 分析 du niveau TABLE effectuée。- 页面分析......................................:1112 - 扩展分析...... .....................: 139 - Commutateurs d'extension....................... ........: 138 - Moyenne des pages par extension.......................: 8.0 - Densité d'analysis [meilleure valeur: valeur réelle].......: 100.00% [139:139] - Fragmentation d'analyze logique........: 0.00% - Fragmentation d'analysis d'extension.......................:5.76% - Moyenne d'octets libres par page....... .....:725.6 - Densité de page moyenne(完整)......................:91.03%

DBCC SHOWCONTIG 分析 la table 'Flow'...

表:“流”(1890105774);索引 ID : 1, base de données ID : 5 分析 du niveau TABLE effectuée。- 页面分析......................................:2662 - 扩展分析...... .....................: 337 - Commutateurs d'extension....................... ........: 343 - Moyenne des pages par extension.......................: 7.9 - Densité d'analysis [meilleure valeur: valeur réelle].......: 96.80% [333:344] - Fragmentation d'analyze logique.......: 0.45% - Fragmentation d'analysis d'extension.......................:5.93% - Moyenne d'octets libres par page........ .....:579.2 - Densité de page moyenne(完整)......................:92.84%

D)每个表的详细信息:

对于我数据库中的所有表,每个索引(集群和非集群)的总碎片少于 10%。

发货单:(此表上有 36360 行)(7 列)

Indexes : PK_DespatchNote(Cluster) IX3_DespatchNote_RealType(non unique , non Cluster) FK_DespatchNote_Archived(non unique , non Cluster)  创建表的脚本:

CREATE TABLE [dbo].[DespatchNote](
    [Id] [uniqueidentifier] NOT NULL,
    [Archived] [datetime] NULL,
    [RealType] [uniqueidentifier] NOT NULL,
    [DbOwner] [uniqueidentifier] NOT NULL,
    [RecordVersion] [timestamp] NOT NULL,
    [IsSent] [bit] NULL,
    [SentOn] [datetime] NULL,
 CONSTRAINT [PK_DespatchNote] PRIMARY KEY CLUSTERED 
(
    [Id] 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]

事务:(此表上的 136120 行)(20 列)

索引:PK_Transaction(Cluster) IX3_Transaction_RealType(non unique, non Cluster) FK_Transaction_ReferencedTransactionId(non unique, non Cluster) FK_Transaction_DefaultDisplayLanguageId(non unique, non Cluster) FK_Transaction_CanceledById(non unique, non Cluster) FK_Transaction_Archived(non unique, non Cluster)  脚本创建表:

CREATE TABLE [dbo].[Transaction](
    [Id] [uniqueidentifier] NOT NULL,
    [Archived] [datetime] NULL,
    [RealType] [uniqueidentifier] NOT NULL,
    [DbOwner] [uniqueidentifier] NOT NULL,
    [RecordVersion] [timestamp] NOT NULL,
    [Notes] [ntext] NULL,
    [DefaultDisplayLanguageId] [uniqueidentifier] NULL,
    [ReferencedTransactionId] [uniqueidentifier] NULL,
    [TransactionNumber] [nvarchar](40) NULL,
    [IsCanceled] [bit] NULL,
    [CanceledOn] [datetime] NULL,
    [CanceledById] [uniqueidentifier] NULL,
    [TransactionType] [int] NOT NULL,
    [IsPending] [bit] NOT NULL,
    [IsGenerated] [bit] NOT NULL,
    [PrintCount] [int] NOT NULL,
    [LastPrintDate] [datetime] NULL,
    [AttachedFile] [image] NULL,
    [IsPointOfSalesTransaction] [bit] NOT NULL,
    [IsAffiliatedTransaction] [bit] NOT NULL,
 CONSTRAINT [PK_Transaction] PRIMARY KEY CLUSTERED 
(
    [Id] 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] TEXTIMAGE_ON [PRIMARY]

GO

ALTER TABLE [dbo].[Transaction] ADD  CONSTRAINT [DF_Transaction_TransactionType]  DEFAULT (0) FOR [TransactionType]
GO

ALTER TABLE [dbo].[Transaction] ADD  CONSTRAINT [DF_Transaction_IsPending]  DEFAULT (0) FOR [IsPending]
GO

ALTER TABLE [dbo].[Transaction] ADD  DEFAULT ((0)) FOR [IsGenerated]
GO

ALTER TABLE [dbo].[Transaction] ADD  CONSTRAINT [DF_Transaction_PrintCount]  DEFAULT ((0)) FOR [PrintCount]
GO

ALTER TABLE [dbo].[Transaction] ADD  CONSTRAINT [DF_Transaction_IsPointOfSalesTransaction]  DEFAULT ((0)) FOR [IsPointOfSalesTransaction]
GO

ALTER TABLE [dbo].[Transaction] ADD  CONSTRAINT [DF_Transaction_IsAffiliatedTransaction]  DEFAULT ((0)) FOR [IsAffiliatedTransaction]

流:(此表上的 136120 行)(13 列)

索引: PK_Flow(Cluster)
IX3_Flow_RealType (non unique , non Cluster) FK_Flow_ValidatedById(non unique , non Cluster) FK_Flow_UpdatedById(non unique , non Cluster) FK_Flow_CreatedById(non unique , non Cluster) FK_Flow_Archived(non unique , non Cluster)  脚本创建表:

CREATE TABLE [dbo].[Flow](
    [Id] [uniqueidentifier] NOT NULL,
    [Archived] [datetime] NULL,
    [RealType] [uniqueidentifier] NOT NULL,
    [DbOwner] [uniqueidentifier] NOT NULL,
    [RecordVersion] [timestamp] NOT NULL,
    [CreatedOn] [datetime] NULL,
    [CreatedById] [uniqueidentifier] NULL,
    [UpdatedOn] [datetime] NULL,
    [UpdatedById] [uniqueidentifier] NULL,
    [KeyingFinished] [bit] NULL,
    [IsValidated] [bit] NULL,
    [ValidatedOn] [datetime] NULL,
    [ValidatedById] [uniqueidentifier] NULL,
 CONSTRAINT [PK_Flow] PRIMARY KEY CLUSTERED 
(
    [Id] 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]

产品运动:(此表中有 83631 行)(8 列)

索引:PK_ProductsMovements(Cluster) IX3_ProductsMovements_RealType(non unique, non Cluster) FK_ProductsMovements_DoneById(non unique, non Cluster) FK_ProductsMovements_Archived(non unique, non Cluster)  创建表的脚本:

CREATE TABLE [dbo].[ProductsMovements](
    [Id] [uniqueidentifier] NOT NULL,
    [Archived] [datetime] NULL,
    [RealType] [uniqueidentifier] NOT NULL,
    [DbOwner] [uniqueidentifier] NOT NULL,
    [RecordVersion] [timestamp] NOT NULL,
    [IsDone] [bit] NULL,
    [DoneById] [uniqueidentifier] NULL,
    [DoneOn] [datetime] NULL,
 CONSTRAINT [PK_ProductsMovements] PRIMARY KEY CLUSTERED 
(
    [Id] 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]

如果您想了解更多信息,请告诉我最好的问候谢谢。

4

1 回答 1

0

Your query is basically:

SELECT . . .
FROM [DespatchNote] INNER JOIN
     [Flow]
     ON [DespatchNote].[Id] = [Flow].[Id] INNER JOIN
     [Transaction]
     ON [DespatchNote].[Id] = [Transaction].[Id] INNER JOIN
     [ProductsMovements]
     ON [DespatchNote].[Id] = [ProductsMovements].[Id]
WHERE [DespatchNote].[RealType] = @param42485 AND
      [ProductsMovements].[IsDone] = @param42486 AND
      [DespatchNote].[Archived] IS NULL

First, all your tables have id declared as the primary key. Alas, the lowest hanging fruit is eaten. i Next, the question is about additional indexes. My guess is that an index on DespatchNote(RealType, Archived, id) would help the query. This should reduce the volume of data going into the joins, and might encourage the database engine to use the indexes for the joins.

于 2015-03-17T15:32:46.417 回答