小编Mar*_*ark的帖子

以最少的停机时间重新导入大量数据的最佳方法

我需要每周导入大约 500,000 条包含 IP 查找(只读参考)数据的记录(只有三个 int/bigint cols)。

我真的不想担心将数据与现有表合并,我更愿意清除旧表并重新导入。

理想情况下,运行在数据上的查询将继续运行(我们没有得到很多这样的查询,它们在导入时运行得慢一点是可以接受的,但需要 24/7,所以运行这个“非工作时间”不是一种选择)。

到目前为止尝试过的事情

SSIS:我创建了一个 SSIS 包来截断表和导入 - 运行大约需要 30 秒(真的太长了)。

临时表:导入临时表、截断和复制也需要大约 30 秒。

BCP:批量导入也太慢了(出于某种原因,它比 SSIS 慢(即使没有要维护的索引)-我猜这与 char->int/bigint 事务有关:/

镜台?所以,目前,我想知道如何通过视图读取表,将数据导入镜像表,并更改视图以指向该表......这看起来会很快,但看起来很小对我来说有点hacky。

这似乎应该是一个常见问题,但我找不到推荐的做法 - 任何想法都将不胜感激!

谢谢

sql-server bulk import

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

为什么我收到“由于更新冲突而中止快照隔离事务”?

我们有两张桌子

  1. 父级(Id int 身份、日期日期时间、名称 nvarchar)
  2. 孩子(Id int 身份、ParentId int、日期日期时间、名称 nvarchar)

Child 与 Parent 有外键关系。

我们启用了数据库级读提交快照隔离。

我们只为父和子插入和删除行(无更新)

我们有一个进程(事务)从 Child(然后是 Parent)中删除旧数据

我们有多个其他进程(事务)将新数据插入父(然后是子)

删除过程会定期(但不是所有时间)回滚,即使插入过程没有插入新的子行,这些子行引用删除要删除的父行 - 它只是创建新的父行和一个或多个引用新父级的新子行

删除父行时的错误是:

由于更新冲突,快照隔离事务中止。您不能使用快照隔离直接或间接访问数据库 'Test' 中的表 'dbo.Child' 以更新、删除或插入已被另一个事务修改或删除的行。重试事务或更改更新/删除语句的隔离级别。

我知道人们建议在外键列上建立索引 - 我们不希望在理想情况下(出于空间/性能原因)这样做 - 除非这是使其工作的唯一可靠方法。

注意到这一点:https : //stackoverflow.com/questions/10718668/snapshot-isolation-transaction-aborted-due-to-update-conflict

和相当不错的文章:https : //sqlperformance.com/2014/06/sql-performance/the-snapshot-isolation-level

但这些都没有给我想要的理解:)

sql-server snapshot-isolation

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

对于具有少量表和大量不可变数据的大型数据库,最佳 SQL 服务器备份策略是什么?

我们有一个大型数据库(500GB 并且正在扩展)。95% 以上的数据存储在 3 个表中(一个表有 20 亿多行)。数据在很大程度上是不可变的 - 即一旦添加,它就只能在之后读取。我们无法存档旧数据。

我们正在使用允许压缩备份的 SQL Server 2017,但即便如此,备份和通过网络复制到备份服务器也需要很长时间。

我们想加快这个过程(并且出于灾难恢复目的,在云中备份 - 可能是 Azure) - 差异备份足够小,但我认为我们仍然需要定期进行完整备份(例如每个周末完整备份)每晚的差异对我们来说仍然是一个问题)

我的感觉是使用分区来分割一些合理列上的大表(集群在身份 ID 上),然后我们可以只备份旧分区一次并将它们标记为只读,而无需再次全部备份。

这不是一个理想的情况,因为我们将来需要不断添加更多分区。此外,数据库无法关闭超过几分钟,所以我想我将不得不使用分区制作数据的影子版本,然后进行一些切换,以减少停机时间,这有点冒险和复杂。

如果有人对这种数据库配置有他们认为会更好的备份策略(或者可以确认考虑到我的限制,这似乎是一个好主意)我很高兴听到:)

附加信息:

当前备份计划:

  1. 完整备份(每晚) - 压缩备份大约100 GB(500 GB 未压缩),大约需要40 分钟(压缩)

  2. 日志备份(每 10 分钟) - 几乎是即时的,每个只有大约 20 MB。

现在我知道,对于某些人来说,40 分钟并不是很长的时间,100 GB 也不是一个很大的文件,但我也知道,鉴于 95% 以上的数据是不可变的,并且只能安全备份一次,备份可能需要不到几分钟的时间,并且可能需要几 GB(这是保守的)。

我相信分区是用于帮助管理备份的工具之一,特别是对于这种类型的场景,我希望让有实际经验的人(或我的场景中基于 SQL Server 的替代方案)能够说明一些问题什么对他们有用。

performance sql-server backup sql-server-2017

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

是否可以在只读可用性组辅助上使用“读取未提交”隔离级别?

我们在 SQL 2019 企业版中使用可用性组。我们使用企业功能允许 AG 辅助节点处于只读模式,然后通过使用参数连接到侦听器来对辅助节点运行报告查询ApplicationIntent=ReadOnly

Read Uncommitted出于锁定和性能原因,我们有一些在主数据库上使用隔离级别运行的查询。

似乎在辅助设备上,所有隔离级别都转换为 RCSI,无论指定的锁定/隔离级别如何 - 可能是因为没有可能阻止 AG 同步的锁至关重要。

是否可以在辅助数据库上以“读取未提交”的方式运行查询,这大概也可以确保不采取任何锁定,但是,在某些情况下可以执行得更好,或者对于只读辅助数据库上的查询,它始终必须是 RCSI?

availability-groups snapshot-isolation sql-server-2019 query-performance

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

Azure 备份服务器可以备份参与日志传送的数据库吗?

我们有许多日志传送的 SQL 2017 数据库,我们希望以 15 分钟的时间表开始使用 Microsoft Azure 备份服务器(本地和云)进行备份。

有谁知道 Azure 备份服务器是否可以挂钩 SQL Server 日志传送所做的日志备份?

sql-server log-shipping azure

5
推荐指数
1
解决办法
88
查看次数

为什么只读 AG 辅助数据库上的列存储性能明显较差?

我们有一对 SQL 2019 Enterprise 实例,托管在 Azure 中规格和配置相同的虚拟机中。

它们用于简单的主/辅助可用性组阵列,包含跨少量 AG 的少量数据库。

单个主生产数据库利用由生产代码填充的大型(数十亿行)列存储表,并用于只读分析报告查询 - 这些查询还连接到行存储表以获取附加信息。

我们希望将只读查询卸载到只读 AG 辅助数据库上,以将负载分散到数据库上,因此我们向侦听器提供参数ApplicationIntent=ReadOnly- 这效果很好,并且针对辅助数据库发出查询。

然而,只读查询的持续时间通常比主数据库慢 10 倍。

比较相同的执行计划,我可以看到所有额外的时间都花在读取列存储表上。反复重新运行查询以确保缓存不会对辅助数据库产生任何影响。但在主要方面,我看到了与缓存相关的性能改进,重新运行时立即返回结果。另外,暂时停止AG数据同步也没有任何效果。

比较 IO 统计数据,两者相似。比较列存储对象池和行存储缓冲池中使用的内存,两者也很相似。

这里真的很茫然——我本以为辅助设备的负载要少得多,但资源相同,如果有更好的表现,而不是持续和明显更差的话。

有没有人遇到过这种情况并对我如何改善或至少证明这种情况有任何建议?

columnstore availability-groups azure-vm sql-server-2019 query-performance

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

为什么 sys.fn_hadr_backup_is_preferred_replica 需要这么长时间?有没有更好的办法?

我用来sys.fn_hadr_backup_is_preferred_replica查询每个可用性组副本上的数据库,以确定是否应该在该副本上备份数据库 - 然后,如果该函数返回 true,则检查msdb.dbo.backupset数据库最近是否已备份。

我遇到的问题是该函数需要很长时间才能运行(每个数据库大约 3 秒) - 谁能推荐一个更快的替代方案?

为了回应下面的评论,我目前使用的是 SQL 2012 SP1 (11.0.3000.0) - 但是,我正在创建的查询需要针对多个客户站点上 SQL Server 2012 的多个不同安装,因此,即使这个系统功能在后续的更新中得到了改进,遗憾的是我可能无法强迫人们更新。

sql-server backup availability-groups

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

sys.dm_exec_requests 中的 request_id 是什么以及它如何变化?

根据MSDN,request_idsys.dm_exec_requests

“请求的 ID。在会话上下文中是唯一的。不可为空。”

从随意观察来看,它总是显示为 0。

有人能告诉我,对于给定的会话,这个 id 怎样才能大于 0?是否可以用一些sql来重现这个?

谢谢!

sql-server t-sql dmv

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

以有效的方式获取错误日志位置

我正在使用这个 sql 来获取我的错误日志位置:

EXEC xp_readerrorlog 0, 1, N'Logging SQL Server messages in file'
Run Code Online (Sandbox Code Playgroud)

但是,有时我有非常大的日志文件(大约 1gb,我无法控制这些文件的循环)上面的查询需要大约 10 秒才能在这些大文件上运行,这太长了。

鉴于这段文本总是在文件的前几行,如果我能说“给我前 1 行然后停止阅读”就好了,但我认为 xp_readerrorlog 不支持这一点?

或者,如果我知道文件中第一行的日期,我可以指定一个日期范围,如下所示:

DECLARE @startDate DATETIME
DECLARE @endDate DATETIME
SET @startDate = '2016-01-28 12:00:00'
SET @endDate = DATEADD(mi, 5, @startDate)
EXEC xp_readerrorlog 0, 1, N'Logging SQL Server messages in file', NULL, @startDate, @endDate
Run Code Online (Sandbox Code Playgroud)

哪个快得多。但是,我不知道如何计算出这个日期——在许多情况下,它与实例进程的开始时间几乎相同(SELECT login_time FROM sysprocesses WHERE spid = 1但这不能保证)

我还尝试使用master..xp_instance_regread从 读取日志文件位置SOFTWARE\Microsoft\MSSQLServer\MSSQLServer\Parameters,但这似乎并不总是准确的。

有没有人对我如何以有效的方式计算日志文件位置有任何建议,即使我的日志文件很大。

sql-server t-sql error-log

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