小编Ken*_*her的帖子

为什么添加 TOP 1 会显着降低性能?

我有一个相当简单的查询

SELECT TOP 1 dc.DOCUMENT_ID,
        dc.COPIES,
        dc.REQUESTOR,
        dc.D_ID,
        cj.FILE_NUMBER
FROM DOCUMENT_QUEUE dc
JOIN CORRESPONDENCE_JOURNAL cj
    ON dc.DOCUMENT_ID = cj.DOCUMENT_ID
WHERE dc.QUEUE_DATE <= GETDATE()
  AND dc.PRINT_LOCATION = 2
ORDER BY cj.FILE_NUMBER
Run Code Online (Sandbox Code Playgroud)

这给了我可怕的表现(就像从不费心等待它完成一样)。查询计划如下所示:

在此处输入图片说明

但是,如果我删除它,TOP 1我会得到一个看起来像这样的计划,它会在 1-2 秒内运行:

在此处输入图片说明

下面更正 PK 和索引。

TOP 1更改查询计划这一事实并不让我感到惊讶,我只是有点惊讶它使情况变得更糟。

注意:我已经阅读了这篇文章的结果并理解了 aRow Goal等的概念。我很好奇的是如何更改查询以使其使用更好的计划。目前我正在将数据转储到临时表中,然后从中取出第一行。我想知道是否有更好的方法。

编辑对于事后阅读本文的人,这里有一些额外的信息。

  • Document_Queue - PK/CI 是 D_ID,它有大约 5k 行。
  • Correspondence_Journal - PK/CI 是 FILE_NUMBER,CORRESPONDENCE_ID,它有大约 140 万行。

当我开始时,没有其他索引。我在 Correspondence_Journal (Document_Id, File_Number) 上找到了一个

performance sql-server sql-server-2008-r2 query-performance performance-tuning

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

您可以将 COUNT DISTINCT 与 OVER 子句一起使用吗?

我正在尝试提高以下查询的性能:

        UPDATE  [#TempTable]
        SET     Received = r.Number
        FROM    [#TempTable] 
        INNER JOIN (SELECT  AgentID,
                            RuleID,
                            COUNT(DISTINCT (GroupId)) Number
                    FROM    [#TempTable]
                    WHERE   Passed = 1
                    GROUP BY AgentID,
                            RuleID
                   ) r ON r.RuleID = [#TempTable].RuleID AND
                          r.AgentID = [#TempTable].AgentID                            
Run Code Online (Sandbox Code Playgroud)

目前我的测试数据大约需要一分钟。我对这个查询所在的整个存储过程的更改的输入量有限,但我可能会让他们修改这个查询。或者添加索引。我尝试添加以下索引:

CREATE CLUSTERED INDEX ix_test ON #TempTable(AgentID, RuleId, GroupId, Passed)
Run Code Online (Sandbox Code Playgroud)

它实际上使查询所需的时间增加了一倍。我用非聚集索引得到了同样的效果。

我尝试按如下方式重新编写它,但没有任何效果。

        WITH r AS (SELECT  AgentID,
                            RuleID,
                            COUNT(DISTINCT (GroupId)) Number
                    FROM    [#TempTable]
                    WHERE   Passed = 1
                    GROUP BY AgentID,
                            RuleID
            ) 
        UPDATE  [#TempTable]
        SET     Received = r.Number
        FROM    [#TempTable] 
        INNER JOIN r …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2008-r2

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

什么时候动态端口是“动态的”?

我今天正在Dynamic Ports与我的一位同事讨论,可以使用一些帮助来澄清他们的工作方式。

第一个问题:如果IPALL TCP Dynmaic Ports设置是一个特定的数字(比如 1971),这是否表示您有一个 1971 的静态端口或一个当前为 1971 的动态端口,并且可能会在将来的某个时候发生变化。

在此处输入图片说明

第二个问题:这是我最好奇的一个。我们有一个实例,IPALL TCP Dynmaic Ports通过数十次实例重启,该实例具有相同的端口(设置中的值)数年。是什么导致实例重启后动态端口实际发生变化?

sql-server dynamic-ports tcpip

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

归档除当前年份以外的所有数据并同时对表进行分区的最佳方法是什么

任务

从一组大表中归档除滚动 13 个月之外的所有内容。存档数据必须存储在另一个数据库中。

  • 数据库处于简单恢复模式
  • 这些表从 5000 万行到几十亿行,在某些情况下每个表占用数百 GB。
  • 表当前未分区
  • 每个表在不断增加的日期列上都有一个聚集索引
  • 每个表额外有一个非聚集索引
  • 对表的所有数据更改都是插入
  • 目标是最大限度地减少主数据库的停机时间。
  • 服务器是 2008 R2 Enterprise

“归档”表将有大约 11 亿行,“活”表大约有 4 亿行。显然存档表会随着时间的推移而增加,但我希望活动表也能合理快速地增加。至少在接下来的几年里说 50%。

我曾考虑过 Azure 扩展数据库,但不幸的是我们在 2008 R2 并且可能会在那里停留一段时间。

当前计划

  • 创建一个新的数据库
  • 在新数据库中创建按月(使用修改日期)分区的新表。
  • 将最近 12-13 个月的数据移动到分区表中。
  • 对两个数据库进行重命名交换
  • 从现在的“归档”数据库中删除移动的数据。
  • 对“归档”数据库中的每个表进行分区。
  • 将来使用分区交换来归档数据。
    • 我确实意识到我必须换出要存档的数据,将该表复制到存档数据库,然后将其交换到存档表中。这是可以接受的。

问题: 我正在尝试将数据移动到初始分区表中(实际上我仍在对其进行概念验证)。我正在尝试使用 TF 610(根据数据加载性能指南)和一个INSERT...SELECT语句来移动数据,最初认为它会被最少记录。不幸的是,每次我尝试它都被完全记录。

在这一点上,我认为我最好的选择可能是使用 SSIS 包移动数据。我试图避免这种情况,因为我正在处理 200 个表,并且我可以通过脚本轻松生成和运行任何我可以做的事情。

我的总体计划中是否遗漏了任何内容,SSIS 是快速移动数据和最少使用日志(空间问题)的最佳选择吗?

没有数据的演示代码

-- Existing structure
USE [Audit]
GO

CREATE TABLE [dbo].[AuditTable](
    [Col1] [bigint] NULL,
    [Col2] [int] NULL,
    [Col3] [int] NULL,
    [Col4] [int] NULL,
    [Col5] [int] …
Run Code Online (Sandbox Code Playgroud)

sql-server architecture sql-server-2008-r2 archive

24
推荐指数
1
解决办法
7949
查看次数

sys.partition.rows 列有多准确?

系统视图sys.partitions有一列“行”,它是给定分区中的总行数。对于未分区的表(或只有一个分区,取决于您如何看待它),此列给出了表中的行数。

我很好奇这个列有多准确,我是否可以用它代替SELECT COUNT(1) FROM TableName. 我做了一些实验,创建一个表并添加几千行,删除几百行,再添加几千行等等,而且计数一直都在。但是,我有一张包含大约 7 亿行和几个索引的表。sys.partitions聚集索引的行再次失效,但是其他索引显示出一些细微的变化 (+-20k)。

有谁知道这一行是如何计算的,以及它是否像看起来一样准确?

sql-server sql-server-2008-r2 partitioning count sql-server-2012

14
推荐指数
1
解决办法
4400
查看次数

在 SSIS 包中创建事务的问题

我正在处理需要使用事务的包,但我目前收到以下错误:

SSIS package "CATS-Package.dtsx" starting.
Information: 0x4004300A at Data Flow Task, SSIS.Pipeline: Validation phase is beginning.
Information: 0x4001100A at CATS-Package: Starting distributed transaction for this container.
Error: 0xC001401A at CATS-Package: The SSIS Runtime has failed to start the distributed transaction due to error 0x8004D01B "The Transaction Manager is not available.". The DTC transaction failed to start. This could occur because the MSDTC Service is not running.
SSIS package "CATS-Package.dtsx" finished: Failure.
Run Code Online (Sandbox Code Playgroud)

以下是我目前所知道的:

  • 2012年套餐
  • 我正在包部署中运行
  • TransactionOption 属性设置为必需
  • 针对 2008 R2 实例运行 …

sql-server ssis sql-server-2008-r2 distributed-transactions ssis-2012

13
推荐指数
1
解决办法
7961
查看次数

使用 STATISTICS_NORECOMPUTE 的可取性

我最近参与维护一组具有一些有趣索引问题的数据库。最让我恼火的是开发、测试、模型和生产机器之间的指标差异。由于差异使得调优查询变得相当困难,因此同步它们是我的第一个项目之一。

当我比较了测试和模型环境时,我注意到模型环境中的大多数索引都STATISTICS_NORECOMPUTE设置为 ,ON而测试中的索引没有。在所有环境中,都有更新所有数据库统计信息的夜间作业。

我以前从未处理过STATISTICS_NORECOMPUTE,所以这里是我的问题。处理此设置时是否有任何最佳做法?如果我在一天结束时进行统计更新,最好打开STATISTICS_NORECOMPUTE所有索引的所有环境?或者有充分的理由不这样做吗?

编辑:我发现了金佰利特里普的关于这一主题的博客之一在这里,似乎表明STATISTICS_NORECOMPUTE应谨慎充其量只能使用。但我仍然担心在全球范围内关闭它。有没有人试过这个,他们经历了什么?

index sql-server statistics sql-server-2008-r2

11
推荐指数
1
解决办法
7444
查看次数

用户 `dbo` 和存储在 sys.databases 中的数据库的所有者有什么区别

我们最近遇到了一个问题,其中dbo数据库中的用户具有sidowner_sidin不匹配的sys.databases。我了解数据库的所有者与角色的成员有何不同,db_owner但我一直认为用户dbo是数据库的实际所有者。不是这样吗?如果是的话有没有之间的任何真正的差异dbo,什么是中sys.databases

security sql-server

11
推荐指数
1
解决办法
7558
查看次数

将 SELECT 授予用户和将他们添加到 db_datareader 角色之间有区别吗?

我被要求为数据库中的所有表授予SELECT,INSERTUPDATE给定用户。我最终将用户添加到db_datareader,并给予他们INSERTUPDATE在数据库级别。

但这让我想到,SELECT在数据库级别授予用户权限或将它们添加到db_datareader角色之间有什么区别(如果有)?是否有任何一种或另一种最佳实践?

security sql-server permissions role

10
推荐指数
1
解决办法
9069
查看次数

在聚集索引上重建,为什么数据大小会缩小?

当我们对一个表的聚集索引进行重建时,该表中有大约 15GB 的数据并且数据大小缩小到 5GB,这怎么可能?删除了什么样的“数据”?

数据大小我指的是 DBCC sp_spaceused 的“数据”列

在聚集索引上重建之前:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    39169656 KB 15857960 KB 22916496 KB 395200 KB
Run Code Online (Sandbox Code Playgroud)

在聚集索引上重建后:

name                  rows        reserved    data        index_size  unused
LEDGERJOURNALTRANS    43583730    29076736 KB 5867048 KB  22880144 KB 329544 KB
Run Code Online (Sandbox Code Playgroud)

用于重建的 TSQL:

USE [DAX5TEST]
GO
ALTER INDEX [I_212RECID] ON [dbo].[LEDGERJOURNALTRANS] REBUILD PARTITION = ALL WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, ONLINE = ON, SORT_IN_TEMPDB = OFF, DATA_COMPRESSION = PAGE, FILLFACTOR …
Run Code Online (Sandbox Code Playgroud)

sql-server clustered-index

10
推荐指数
3
解决办法
4538
查看次数