3

我有一个场景,用户在屏幕上的操作会导致在大约 50 个不同的表中实时创建新记录。用例的设计使得由于用户操作而创建的新记录需要立即供用户进行更改。所以没有离线或延迟创建的可能性。

话虽如此,明显的问题是 - 插入语句(以及一些额外的操作语句)在事务中,这使得它成为一个非常冗长的事务。这会运行大约 30 秒,通常会导致超时或阻止其他查询。

原子性需要事务。有没有更好的方法可以拆分事务并仍然保持一致性?或者有什么其他方法可以改善目前的情况?

4

2 回答 2

5

插入查询正在等待当时并行运行的其他(主要是选择)查询

您应该考虑使用基于行版本的隔离级别,也就是。SNAPSHOT,因为在基于行版本的隔离级别下,读取不会阻塞写入并且写入不会阻塞读取。我将首先启用 READ_COMMITTED_SNAPSHOT 并使用它进行测试:

ALTER DATABASE [...] SET READ_COMMITTED_SNAPSHOT ON;

我建议阅读链接的文章,以了解行版本控制所隐含的含义和权衡。

于 2012-03-22T06:33:07.337 回答
1

根据评论交流,我相信您必须同时查看插入事务和并发查询。您希望在不丢失事务完整性的情况下适应它们的负载。可用的优化技术包括:

  1. 每当您在经常出现或执行缓慢的查询的执行计划中发现大型数据集上的缓慢构造(例如,嵌套循环)时,添加访问索引。

  2. 添加覆盖索引。除了查找列之外,这些索引还包含其他列,它们使特定查询可以完全避免访问表。当表很宽而覆盖索引很窄时,这尤其有效,但它也可用于避免同一行的不同列上的 UPDATE 和 SELECT 之间的锁定问题。

  3. 非规范化。例如,切换一些查询以访问索引视图而不是物理表,或者在更新主表时使用触发器提供辅助表。这些是昂贵的双刃技术,只应考虑用于解决已证明的顶级瓶颈。

只做那些测得的加速非常大的更改,因为这些技术在性能方面都不是免费的。永远不要在每一步都进行性能测量的情况下进行优化。

以下内容是微不足道的,但为了完整起见,让我们提一下 - 在您分析执行计划和生产使用时,让您的统计信息保持最新(ANALYZE根据UPDATE STATISTICS您的数据库引擎)。

于 2012-03-22T09:44:00.377 回答