SQL - 有没有更好的方法来处理一个表上的许多事务?

时间:2016-08-14 23:56:03

标签: mysql sql-server database

所以说你在一些关系数据库(SQL Server,MySQL,等等)中有一个SQL表。假设您有500个任务,每15分钟运行一次。每个任务都将删除与该任务相关的一部分数据,插入与该任务相关的新数据,然后外部源将选择与该任务相关的数据。

根据我的经验,这不可避免地导致死锁,超时以及所有选择的低于标准的性能,即使在进行脏读时也是如此。

您可以尝试尽可能地错开任务的开始时间,但它并没有真正解决问题。有很多任务总会有重叠。

您可以尝试使用更好的CPU来升级服务器以处理连接,但这对于仅仅500个任务来说非常昂贵。

所以我所做的就是重复表Schema,并为每个任务提供了自己的独立表格。 此外,在为表构造新数据时,它所做的只是插入到新表中,然后使用该表翻转当前表的名称。

CREATE TABLE Task001_Table_Inactive

批量将新数据插入Task001_Table_Inactive

DROP TABLE Task001_Table_Active

RENAME Task001_Table_Inactive Task001_Table_Active

优点:

- 快速处理。 SQL从不擅长持续删除。只是批量插入和翻转名称的能力大大减少了任务的处理时间。

-Scalable。既然所有这些插入和删除都不是经常在一个桌面上进行争夺,那么我可以在云中的一台非常便宜的机器上运行许多任务。

- 防碎片。由于每次都会重新创建表,因此任何因持续删除而困扰系统的碎片问题不再是问题。

- 尽可能快地选择WITH OUT需要脏读。由于插入是在单独的表中完成的,因此外部源完成的select语句将尽可能快,无需进行脏读。这是imo的最大优势!

- 快速迁移。最终,即使使用此设置,我也会执行太多任务并耗尽处理能力。因此,如果我需要将任务迁移到另一个服务器,那么复制两个表而不是blob表上的hacky和极慢的select语句就是一个简单的事情......

-Indexability。当表格太大(300毫米行+)时,您无法将其编入索引。无论它只是因为事务缓冲区限制而突然停顿几天而放弃。这就是SQL的方式。通过将巨大的blob表分割成较小的表,您可以成功编制索引。将此与并行化相结合,您可以比在大表上进行索引时更快地索引所有数据。

缺点:

- 难以在GUI中导航表格

- 使select / schema alter语句变得有点棘手,因为现在它必须对每个表执行某种游标,例如% Table %并将SQL命令应用于每个表。

那么,为什么许多SQL爱好者如果有很多优势就不喜欢Schema重复?有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:0)

没有足够的信息建议......,但应考虑以下内容:

  • 快照隔离 https://msdn.microsoft.com/en-us/library/ms173763.aspx 除非正在恢复数据库,否则SNAPSHOT事务在读取数据时不会请求锁定。读取数据的SNAPSHOT事务不会阻止其他事务写入数据。写入数据的事务不会阻止SNAPSHOT事务读取数据。
  • 使用事务复制/日志传送/镜像/更改数据捕获等来卸载主表
  • 而不是删除,软删除(更新IsDeleted标志或维护xxxx_deleted表)是一个选项。

如果系统(数据库,硬件,网络架构)设计得当,即使每秒有数千个DML请求,也没有问题。

答案 1 :(得分:0)

在Microsoft SQL Server中,如果您的任务从未触及不属于它们的行,您可以尝试使用乐观或悲观版本控制 - Snapshot Isolation in SQL Server

根据您的具体情况,读取提交快照隔离(RCSI)或快照隔离级别将起到作用。如果两者似乎都适合你,我会推荐前者,因为它会导致更少的性能开销。