小编Wad*_*deH的帖子

对相当大的表 (2m) 上的错误查询的索引帮助

我正在寻找一些帮助。我有一个针对相当大的表(200 万条记录)运行的查询。

我一直在努力让索引有效地工作。还有一些针对此表的其他查询,但这是迄今为止最常见的查询。我很难让它在 1 秒内执行,并且经常看到它使用分析器在 3 到 5 秒内运行。

它可能会尽可能快,但我希望得到一些输入来确认/拒绝。

请注意:开发人员根本不会更改查询或架构。只能在数据库中进行优化,不能更改架构。

桌子:

CREATE TABLE [dbo].[Notifications](
[ntID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[NotificationID] [int] NOT NULL,
[NotificationType] [nvarchar](50) NOT NULL,
[UserName] [nvarchar](50) NULL,
[CreatedBy] [nvarchar](50) NULL,
[CreatedOn] [datetime] NULL,
[Status] [nvarchar](50) NOT NULL,
[Result] [nvarchar](50) NULL,
[Extension] [nvarchar](50) NULL,
[ShiftRate] [nvarchar](255) NULL,
[ResponseMinutes] [int] NULL,
[ResponseWindow] [datetime] NULL,
[caNotificationID] [int] NULL,
[AwardedBy] [nvarchar](50) NULL,
[AwardedOn] [datetime] NULL,
[CancelledBy] [nvarchar](50) NULL,
[CancelledOn] [datetime] NULL,
[CancelledReasonID] [int] NULL,
[CancelledReasonText] [nvarchar](255) NULL, …
Run Code Online (Sandbox Code Playgroud)

index sql-server index-tuning nonclustered-index sql-server-2016

8
推荐指数
1
解决办法
414
查看次数

慢循环,查询改进辅助

我正在创建一个数据仓库。我以 5 分钟的间隔创建了一个时间维度 (Dim_Time)。小时聚合将具有 [分钟] = NULL。出于本示例的目的:

CREATE TABLE [dbo].[Dim_Time](
    [TimeID] [int] IDENTITY(1,1) NOT NULL,
    [StartDateTime] [datetime] NULL,
    [Hour] [int] NULL,
    [Minute] [int] NULL,
  CONSTRAINT [PK_Dim_Time] PRIMARY KEY CLUSTERED 
  ([TimeID] ASC)
  ) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

然后我有一个传入表,它每 5 分钟从 OLTP 数据库更新一次。

CREATE TABLE [dbo].[Stg_IncomingQueue](
    [IncomingID] [int] IDENTITY(1,1) NOT NULL,
    [CustomerID] [int] NOT NULL,
    [TimeID] [int] NULL,
    [InsertTime] [datetime] NULL,
 CONSTRAINT [PK_IncomingQueueMonitor] PRIMARY KEY CLUSTERED 
([IncomingID] ASC)
) ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

然后我有以下 While 循环。其目的是获得与特定传入行相关的正确 5 分钟时隙 (TimeID):

WHILE 0 < (SELECT COUNT(*) …
Run Code Online (Sandbox Code Playgroud)

sql-server t-sql sql-server-2016

4
推荐指数
1
解决办法
271
查看次数

查询执行计划很糟糕,直到更新统计信息

我希望你们能在这里帮助我。我们的应用程序每 3 秒轮询一次消息表,寻找要发送的通知。这适用于我们所有的客户(单租户数据库),除了一个。他们将一天 23 小时没有活动,然后一次加载数千条消息(3000+)。在其他情况下,这个卷什么都不是,我们可以轻松处理它,除了在这种情况下,下面的 SQL 查询需要大约 30 秒才能运行,并且随着队列在更新时备份而变得更糟,需要排他锁和因此阻止所有其他查询,因此问题会导致各种破坏。这都是由于糟糕的查询计划造成的。

我们每天早上 5 点进行每日重新索引(重组 < 30%,重建 > 30%,忽略 <5%)以及更新统计信息。这些都来自 Ola Hallengren 维护解决方案。我们也在 SQL Server 2016 上并且完全是最新的 (13.0.5492.2)

我手头没有这 2 个计划,但基本上坏计划会执行 MessagesSent 表(3.5m 行)的全表扫描。

我的理论是,由于查询一整天都没有返回任何内容,因此某些部分没有执行,因此错误查询是最有效的 SQL 查询。

这将在刷新查询计划后继续,因为它只生成相同的计划,但是当我在 MessagesSent 表上更新统计信息时,创建好的计划并且一切正常,查询在大约 10-30 毫秒内执行。

有谁知道我如何微调它以始终使用更好的计划,即使查询返回的数据不存在?作为修补程序,我们向应用程序添加了重新编译选项,但我认为这不是每 3 秒执行一次的查询的理想解决方案。

这是查询:

WITH TopMessage
    AS
    (
        SELECT TOP 1 ID, BatchID FROM MessagesSent 
        JOIN Units ON Unit = idUnit 
        WHERE   MessageDate <= GETDATE() 
          AND         Active = 'True' 
          AND         Status = 'Queued' 
          AND NOT(DialString = 'null') 
          AND           Unit = ('29') …
Run Code Online (Sandbox Code Playgroud)

sql-server statistics execution-plan sql-server-2016

4
推荐指数
2
解决办法
673
查看次数