我有一个SQL Server表,其中有1.6亿多条记录,这些记录具有来自UI、批处理作业等的连续CRUD操作,基本上来自多个源
目前,我已经将表分区为一列,以便在表上获得更好的性能。
我遇到了内存中的表,它可以用于频繁更新的表,而且如果更新来自多个源,它不会锁定,而是会维护行版本控制,因此使用这种方法进行并发更新更好。
那么,在这种情况下,我有什么选择呢?
对表进行分区或在内存中创建表
正如我所读到的,当表被分区时,SQL服务器不支持内存中的表。
在这种情况下,内存表或分区表的更好选项是什么。
这取决于情况。
内存表在理论上看起来很棒,但你确实需要花时间学习细节,才能做出正确的实现。你可能会发现一些细节令人不安。例如:
- 内存表中没有并行插入,与SSD中存储的传统表中的并行插入相比,这会使行的创建速度变慢
- 内存中的表索引中并不是所有基于dis的索引支持的索引操作都可用
- 并非所有数据类型都受支持
- 存在不受支持的功能和T-SQL构造
- 你可能需要比你想象的更多的RAM
如果你准备为使用Hekaton付出代价,你可以从阅读它的白皮书开始。
分区本身也有好处,但不能保证它会治愈你的系统。只有特定的查询和案例场景才能从中受益。例如,如果你99%的工作负载都在一个分区中处理数据,你可能根本看不到优化。另一方面,如果您的报告基于历史数据,并且您的插入/更新/删除触及另一个分区,则会更好。
这两种技术都很好,但需要仔细检查和应用。通常,人们相信使用一些新技术会解决他们的问题,而只要应用一些基本概念就可以解决问题。
例如,您说您正在执行超过1.6亿条记录的CRUD。问问自己:
- 是我的表规范化的-当数据以规范化的方式存储时,你会得到两件事-首先,你将只对部分数据执行CRUD,引擎可能只读取特定查询所需的数据(不需要支持索引(
- 我的T-SQL语句一行接一行地写得好吗?在循环中调用存储过程或不批量处理数据是缓慢查询的常见来源
- 哪些是阻塞和死锁查询-例如,有可能一个长时间运行的查询会阻塞所有插入-首先识别这些类型的问题,并尝试通过数据预计算(索引视图(或创建覆盖索引(也可以使用include列进行筛选(来解决这些问题
- 读写器被阻止-你可以尝试不同的隔离级别来解决这类问题-RCSI是Azure默认的隔离级别。您可能需要在TempDB使用的RAMDISK中添加更多RAM,但由于您正在考虑Hekaton,与它(或分区(相比,这将更容易测试(和回滚(