SQL Server如何将大json上传到列中,性能问题

Ska*_*ary 1 sql-server update json performance-tuning

当 nvarchar(max) 列只有几 MB 数据时,我在表上的单行插入/更新语句上遇到性能不佳的情况。

这是我的表结构:

CREATE TABLE [dbo].[tbl_set_Cart](
    [ID] [int] NOT NULL,
    [AS400_CUSTOMER_COD] [nvarchar](50) NOT NULL,
    [AS400_LISTIN] [int] NOT NULL,
    [VALUE] [nvarchar](max) NOT NULL,
    [DELIVERY_COSTS] [nvarchar](max) NOT NULL,
    [ITEMS_COUNT] [int] NOT NULL,
    [ITEMS] [nvarchar](max) NOT NULL,
    [KIND] [int] NOT NULL,
    [CHECKOUT_INFO] [nvarchar](max) NOT NULL,
    [ISSUES] [nvarchar](max) NOT NULL,
    [LAST_CHECK] [datetime] NOT NULL,
    [USER_ID] [int] NOT NULL,
    [IMPERSONATED_USER_ID] [int] NOT NULL,
    [OVERRIDE_PRICES] [bit] NOT NULL,
    [HAS_ISSUE] [bit] NOT NULL,
    [IS_CONFIRMED] [bit] NOT NULL,
    [IS_COLLECTED] [bit] NOT NULL,
    [_METADATA] [nvarchar](max) NOT NULL,
 CONSTRAINT [PK_tbl_set_Cart] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
Run Code Online (Sandbox Code Playgroud)

这是更新语句的示例

DECLARE @p0 AS INT = [cart_id];
DECLARE @p1 AS INT = [entry_count];
DECLARE @p2 AS NVARCHAR(MAX) = '..document..' --~8MB;

UPDATE [dbo].[tbl_set_Cart]
SET [ITEMS_COUNT] = @p1, [ITEMS] = @p2
WHERE [ID] = @p0
Run Code Online (Sandbox Code Playgroud)

在数据库的同一台机器上执行此命令(开发环境,因此没有其他工作负载),我得到了以下性能:

在此输入图像描述

将文本加载到 SQL Server 中的速度如此之慢,这真的让我感到惊讶,所以我要问的是是否有更好的方法来实现这一点。

该文档是一个大的 JSON,不会超过 10MB 的数据(我已经在最坏的情况下完成了上面报告的基准测试),如果性能提高,我可以毫无问题地将其转换为 BLOB 或其他数据结构。如果这是一个更好的主意,我还可以使用存储过程来上传大文本。

环境:

Windows Server 2019 16 逻辑处理器 2.1 GHz 和 Microsoft SQL Server Standard(64 位)版本 15.0.2070.41,具有 4GB 预留 RAM,已许可的 16 核。

(这是一个仅用于开发的环境,在这种情况下,我是唯一一个没有运行其他程序或计划活动的人。)

我在这里再次测试了不同的购物车(小一点)(客户统计数据)和执行计划。

在此输入图像描述

链接在这里: https: //www.brentozar.com/pastetheplan/?id =SJcPhDUFK

在此输入图像描述

如果我插入新行,速度会更快:

在此输入图像描述

链接在这里: https: //www.brentozar.com/pastetheplan/?id =S1FDjD8KF

在此输入图像描述

对于插入语句,我使用了 SQL Server 生成的数据(任务 -> 脚本表 -> 仅数据)

我期望实现的是更新时间<0,5s

在我的场景中,json 通常一开始就很小,然后逐渐增加,直到我正在测试的大小。我可以开始考虑将它们存储为文件吗?

我已经在日志文件中预先分配了空间。并再次检查恢复模式是否设置为简单。我可以做些什么来进一步提高绩效?

Pau*_*ite 6

您的缓慢更新计划表明等待时间很长LOGBUFFER

日志缓冲区等待

您应该检查数据库的日志文件的存储速度是否足以满足工作负载的需要。

增加实例可用的 RAM 量也可能有一些好处。等待PAGEIOLATCH_EX时间也相当长,为 361ms。

正如大卫·布朗建议的那样,你还可以:

  • COMPRESSJSON 将一些 IO 转移到 CPU。
  • 考虑“行外大值类型”表选项,以在聚集索引中获取更多行/页,并减少更新时的迁移以减少等待PAGEIOLATCH