标签: sql-server-2012

加入前过滤表

我有一个存储过程,它使用 Id 列表填充临时表 #employee_benefits。该表最终大约有 10,000 行长。下面的查询然后从一个名为 EmployeeBenefitData 的表中进行选择,该表有大约 400 万行。

SELECT  ebd.EmployeeBenefitDataId, ebd.EmployeeBenefitId, ebd.[DataDefinitionId]
FROM    #employee_benefits eb
INNER JOIN EmployeeBenefitData ebd ON eb.EmployeeBenefitId = ebd.EmployeeBenefitId
Run Code Online (Sandbox Code Playgroud)

瓶颈是 EmployeeBenefitData 表上的索引扫描。它首先进行索引扫描,然后将其加入临时表。临时表充当过滤器,这意味着在连接之前扫描所有数据的效率非常低。我添加了以下代码以将扫描更改为搜索并显着减少所需的读取量。

DECLARE @MinEmpBenId INT, @MaxEmpBenId INT

SELECT @MinEmpBenId = MIN(EmployeeBenefitId), @MaxEmpBenId = MAX(EmployeeBenefitId)
FROM #employee_benefits

SELECT  ebd.EmployeeBenefitDataId, ebd.EmployeeBenefitId, ebd.[DataDefinitionId],
        dd.TypeId, dd.DataDefinitionId, dd.Name, ebd.[Value], ebd.[Date], ebd.[Text]
FROM    #employee_benefits eb
INNER JOIN EmployeeBenefitData ebd ON eb.EmployeeBenefitId = ebd.EmployeeBenefitId
INNER JOIN DataDefinition dd ON ebd.DataDefinitionId = dd.DataDefinitionId
WHERE   ebd.EmployeeBenefitId >= @MinEmpBenId AND ebd.EmployeeBenefitId <= @MaxEmpBenId
Run Code Online (Sandbox Code Playgroud)

它对客户端统计数据产生了巨大的影响 …

performance sql-server sql-server-2012 query-performance

6
推荐指数
1
解决办法
3742
查看次数

在 SQL Server 中保留默认的最大内存 2147483647 MB​​ 值,这是一种不好的做法吗?

基于该 msdn 页面: 服务器内存设置,最好保留 SQL-Servers min 和 max memory 的默认值以使其保持动态...

根据我通过教程学到的知识,您应该始终定义一个最大值,关于最小值,我没有听说过太多。我正在使用简单的旧 perfmon 监视我的页面文件,我意识到很少发生磁盘交换,一旦它几乎导致服务器崩溃。

这可能与 SQL Server 中的默认最大内存设置有关吗?数据库大约为 150 GB,内存为 48 GB,该机器上没有其他应用程序在运行。

另外,为什么你应该有一个最小值?我知道太低的值会阻止 SQL-Server 启动,我知道 SQL-Server 将内容保存在内存中,因此不会尝试释放它的缓存。

我正在使用 SQL-Server 2012,在此先感谢您!

performance sql-server memory sql-server-2012

6
推荐指数
1
解决办法
2万
查看次数

有没有办法在 Always on 下最小化记录插入?

我有一个处于FULL恢复模式的主数据库,它是Always On组的一部分。有没有办法在FULL恢复模式下最小化记录插入操作?

我有一个每天执行的进程,并在表中插入几百万条记录。随着操作的继续,事务日志文件的大小急剧增加(从 1 GB 到 40 GB)。

正如我所读到的,我可以使用一些未完INSERT全记录操作的变体,但我担心切换恢复模型的效果?

t-sql sql-server-2012 transaction-log availability-groups bulk-insert

6
推荐指数
1
解决办法
4825
查看次数

重新启动 SQL Server 时标识值跳转

我们刚刚从 SQL Server 2008 R2 切换到 SQL Server 2012。我遇到了标识列的问题:

每当我重新启动 SQL Server 时,每个标识列的种子值都会增加 1000(对于int标识列是 1000,对于bigint它是 10,000)。例如,如果表的下一个int标识值是 3,那么在重新启动 SQL Server 后它将是 1003。如果我再次重新启动 SQL Server,它将是 2003,以此类推。

在谷歌搜索后,我发现它是 SQL Server 2012 中的一个新功能(不知道它的用途),如果您想要旧的身份行为,只有两种解决方案:

  1. 使用序列对象

    这对我来说是不可能的,因为:

    a) 我在 SQL Server 2008 和 2012 中使用相同的数据库。我不能在 2008 中使用序列。

    b) 如果我使用序列,那么我需要更改每个表的保存过程,这对我们来说将是一项繁重的任务。

  2. 使用跟踪标志 272 (-T272)

    我可以使用此解决方案,因为无需对我的应用程序进行任何更改。有人建议添加-T272作为启动参数,之后此 SQL Server 标识将像在以前的版本中一样工作。我做了同样的事情,但它不起作用。

我不想对我的数据库结构进行任何更改。请提出解决方案或解释为什么-T272不起作用。

sql-server identity sql-server-2012

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

GZipStream/DeflateStream 压缩替代方案

我创建了一个简单的 CLR 函数来压缩/解压缩NVARCHAR列:

[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlBinary Compress( string str ){
    if( str == null ){return new SqlBinary();}

    if( String.IsNullOrEmpty( str ) ){str = " ";}

    byte[] bytes = Encoding.Unicode.GetBytes( str );
    using( MemoryStream msi = new MemoryStream( bytes ) ){
        using( MemoryStream mso = new MemoryStream() ){
            using( GZipStream gs = new GZipStream( mso, CompressionMode.Compress ) ){
                msi.CopyTo( gs );
            }
            return new SqlBinary( mso.ToArray() );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的压缩率大约是 4,或者如果我有 1024 …

compression sql-server-2012 sql-clr

6
推荐指数
1
解决办法
2662
查看次数

将 VLDB 迁移到 AlwaysON AG

我已经使用 AlwaysON AG 很长时间了,目前在 120 个数据库和 3 个 AG 组中拥有大约 10TB 的数据,用于 SQL 2012 上的任何应用程序并取得了巨大成功。每个 AG 组在补丁级别 11.0.5058.0 上运行,主数据中心有 2 个同步副本(在不同的 SAN 上),DR 中有 1 个异步副本。迁移一直不是问题,因为没有一个数据库足够大,以至于我无法适应 SAT 早上 12 点到 4 点的维护窗口。

我的问题是,我最后一个迁移到 2012 年的应用程序包含一个 4TB TDE 加密数据库数据库,它比我之前迁移的任何应用程序大 10 倍左右。数据库在大量调优后需要 4 小时才能备份(我讨厌 TDE !!)

由于种子增量,恢复到主副本是即时的,但问题来自必须在添加到可用性组之前备份数据库。4 小时是我的确切停电窗口,我不能再得到更多了。

我迁移应用程序的计划是 -

第一个中断窗口

  1. 从 2008 年到 2012 年的主副本还原数据库

  2. 将应用程序 ARECORD(或 cname 不确定是哪个)更改为主副本

  3. 在单个节点上运行数据库直到下一个中​​断窗口

一周后:

  1. 将数据库添加到可用性组
  2. 将 ARCORD/CNAME 更改为侦听器

我不喜欢这个的地方是我整个星期都用 1 个节点而不是 3 个节点,这很令人担忧。如果其他人对如何实现这一点有任何更好的想法,我很乐意听取您的意见,或在可用性组中使用 VLDB 的人员的任何类型的评论,以及您喜欢/讨厌/喜欢这样做的地方。我正在尝试全力以赴地使用这个软件,到目前为止我一直很喜欢它,但在涉及到 VLDB 迁移时却很担心。

sql-server migration sql-server-2012 availability-groups

6
推荐指数
1
解决办法
649
查看次数

存档后缩小,这也很糟糕吗?

我有一个增长到 20 GB 的数据库,在归档一些数据后,表的实际大小仅为 5GB。备份脚本会将备份副本保存到其他位置。移动 20GB 或 5Gb 确实有所不同,所以我想减小物理尺寸,但如果我不想影响性能,我读到的任何地方都不要缩小。

但是在这种(定期/每季度/每年)归档的情况下,是否仍然建议不要收缩?

database-recommendation shrink sql-server-2012

6
推荐指数
1
解决办法
1311
查看次数

IO 请求时间和更少的写入延迟

我面临着与不断增长的日志文件相关的问题,因此我收到了错误。当我检查 SQL 日志时,我发现以下消息(错误日志中几乎 90% 都填充了这些消息)

SQL Server 遇到 1 次 I/O 请求需要超过 15 秒才能在文件中完成

几乎所有数据库都会发生这种情况,包括 temdb [.mdf 和 .ndf 文件] 以及我也收到以下消息

平均吞吐量:0.34 MB/秒 I/O 饱和度:196 次上下文切换 1210

最后一个未完成的目标:530 avgWriteLatency 2

FlushCache:在 142370 毫秒内清理了 6233 个 buf,384 次写入(避免了 99 个新的脏 buf),用于 db 6:0

我的 temdb 大小和其他数据库和日志文件大小足够大。

历史

  • 以前的开发人员已经多次进行数据库收缩和日志收缩。
  • 所有数据库都处于压缩模式。

我的行动计划

  • 我发现日志文件的初始大小很小,增长了 10%。我计划将初始大小增加 512 MB,增加 512 MB 以获得合理数量的 VLF。

    问题 1:虽然我会在非高峰时段进行工作,但进行这些更改是否有可能损坏我的数据库或日志文件?

    问题二:数据库压缩方式会影响IO操作吗?如果是,我该如何解决?

  • 我计划从防病毒检查中删除所有数据库和日志文件。

  • 我计划将目标恢复时间更改为 < 1 分钟的数据库(特别是 tempdb 和我的数据库)

    问题 3:这会影响我的数据库吗?我的意思是刷新缓冲区和写入磁盘应该可以提高性能,对吗?

    问题 4:我有 3 个 tempdb …

compression sql-server-2012 tempdb transaction-log

6
推荐指数
1
解决办法
1248
查看次数

分页性能,带有子查询、内连接和 where

我正在尝试优化以下查询(这是我能想到的最简化的版本):

SELECT tr.Id, StatusDate
FROM (
    SELECT tr.Id, tr.StatusDate
    FROM mon.ArchivedTaskResults_201504 as tr WITH (NOLOCK)
    INNER JOIN mon.ViewDevicesWithGroups dev WITH (NOLOCK) ON tr.DeviceId = dev.Id
    WHERE tr.ClientId = 4 AND dev.Deleted = 0
) AS tr        
ORDER BY StatusDate DESC
OFFSET 1000000 rows
FETCH NEXT 25 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)

简单查询执行计划

问题是,查询性能与 OFFSET 成正比 - 对于 offset=0 查询在 0.0 秒内执行,但对于 offset=1000000 执行时间约为 23 秒(如果偏移量更大,则可能需要几分钟)。

我几乎可以肯定我的问题可以通过 ArchivedTaskResults 表上的适当聚集索引来解决,但是在尝试了几个小时之后我仍然没有找到好的索引。

ArchivedTaskResults 表真的很大,大约有 50000000 行(50 M)

附加信息:

如果有人能解决我上面描述的问题,我会非常高兴,但说实话,我的真实查询更加奇怪(免责声明:我不是设计这个数据库的人):

SELECT tr.Id, StatusDate
FROM (
    (
        SELECT tr.Id, StatusDate …
Run Code Online (Sandbox Code Playgroud)

performance sql-server sql-server-2012 query-performance

6
推荐指数
1
解决办法
3736
查看次数

由于简单恢复模型中数据库的“CHECKPOINT”,事务日志已满

对于我们在 SQL Server 2012 RTM 上的数据库之一,

正如错误所说,我们几乎无法执行任何故障排除步骤:

" 由于 'CHECKPOINT',事务日志已满

这是一个开发数据库,​​它的备份从未发生过,所以我们甚至无法选择。

尝试缩小日志文件但没有成功并得到以下错误:

日志空间不足 - 由于“检查点”,事务日志已满,出现级联错误

DBCC CHECKDB 大多只是给出错误,因为事务日志因“CHECKPOINT”而已满

我无法将恢复模式更改为完整 - 出现错误,因为“CHECKPOINT”导致事务日志已满

无法备份:同样的错误:

甚至尝试在其他服务器(SQL server 2012 RTM)上分离和附加,但同样的错误:

尝试在数据库上手动执行 CHECKPOINT,但仍然出现相同的错误:

已经在这里参考了这篇文章Simple model database transaction log full 'CHECKPOINT'

由于 'XTP_CHECKPOINT'数据库 'database_name' 的事务日志已满,但没有成功。

注意:我们没有在当前服务器或任何数据库上设置复制。

请帮助,因为我无法找到根本原因并解决此问题!

谢谢!

sql-server sql-server-2012 transaction-log

6
推荐指数
1
解决办法
3万
查看次数