【问题标题】:How to reduce downtime of table during inserts SQL Server如何在插入 SQL Server 期间减少表的停机时间
【发布时间】:2018-03-09 12:31:42
【问题描述】:

我有一张手术台,叫它Ops。我们的客户每隔一秒就会通过网络服务查询该表。

有两个进程影响表:

  1. 删除过期记录(每天)

  2. 插入新记录(每周)

我的目标是在这些过程中将停机时间降至最低。我知道 Oracle,但这是我第一次使用 SQL Server 和 T-SQL。在 Oracle 中,我会进行截断以加快删除过期记录的第一个过程,并进行分区交换以插入新记录。

SQL Server 的分区交换似乎有点难以处理,因为据我所知,必须创建文件组、分区方案和分区函数 (?)。

您对减少停机时间有何建议?

【问题讨论】:

  • 按滑动窗口日期范围进行表分区将允许您清除过期数据并按分区增量加载数据。您需要一个分区函数和方案,但不需要单独的文件组。分区方案可以为所有分区指定相同的文件组。
  • Lock escalation 也可能导致停机。

标签: sql sql-server performance


【解决方案1】:

表未脱机,因为有人正在删除或插入行。该表可以同时读取和更新。

但是,在默认隔离级别READ COMMITTED 下,读者被作者阻止,写者被读者阻止。这意味着SELECT 语句可能需要更长的时间才能完成,因为尚未提交的事务正在锁定SELECT 语句试图读取的某些行。 SELECT 语句被阻塞,直到事务完成。如果事务需要很长时间,这可能是一个问题,因为它显示为表处于脱机状态。

另一方面,在READ COMMITTED SNAPSHOTSNAPSHOT 隔离级别下,读取器不会阻塞写入器,写入器不会阻塞读取器。这意味着SELECT 语句可以与INSERTUPDATEDELETE 语句同时运行而无需等待获取锁,因为在这些隔离级别下SELECT 语句不会请求锁。

您可以做的最简单的事情是在数据库上启用READ COMMITTED SNAPSHOT 隔离级别。启用此隔离级别后,它将成为默认隔离级别,因此您无需更改应用程序的代码。

ALTER DATABASE MyDataBase SET READ_COMMITTED_SNAPSHOT ON

【讨论】:

  • 感谢您的帮助。我相信READ COMMITTED SNAPSHOP 是我需要的。我希望 INSERTS/DELETES 不会阻止 SELECT 语句(或者换句话说......读取)。我还读到以下选项必须设置在您在帖子底部提到的选项之上:ALTER DATABASE <TableName> SET ALLOW_SNAPSHOT_ISOLATION ON
  • @mpdegn。你真的不需要ALTER DATABASE <DataBaseName> SET ALLOW_SNAPSHOT_ISOLATION ON。这是为了启用与 READ COMMITTED SNAPSHOT 隔离级别不同的 SNAPSHOT 隔离级别。要使用 SNAPSHOT 隔离级别,您需要执行以下语句:SET TRANSACTION ISOLATION LEVEL SNAPSHOT。但是,如果您启用 READ COMMITTED SNAPSHOT,这将成为默认隔离级别,因此您无需执行任何操作即可使用它。
【解决方案2】:

如果您的问题是“选择被阻止”,您可以尝试“NO LOCK”提示。但请务必阅读其中的含义。详情可以查看https://www.mssqltips.com/sqlservertip/2470/understanding-the-sql-server-nolock-hint/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多