【问题标题】:OPENJSON poor performance with CROSS/OUTER APPLY and millions of rows使用 CROSS/OUTER APPLY 和数百万行的 OPENJSON 性能不佳
【发布时间】:2017-03-13 18:38:28
【问题描述】:

我有一个包含数百万行和三个相关列的表:

CREATE TABLE [EventSourcing].[EventsTableCompressed](
    [DocumentKey] [nvarchar](200) NOT NULL,
    ...
    [JsonCompressed] [varbinary](max) NOT NULL,
    [JsonDecompressed]  AS (CONVERT([nvarchar](max),Decompress([JsonCompressed]))),
 CONSTRAINT [PK_EventsTableCompressed] PRIMARY KEY CLUSTERED 
(
    [DocumentKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

当我使用集群索引执行搜索时,它按预期进行,例如:

SELECT 
DocumentKey,
JSON_VALUE(JsonDecompressed, '$.MyJsonProperty') as MyJsonProperty
FROM  [EventSourcing].[EventsTableCompressed] C
where DocumentKey> 'RangeInit' and DocumentKey< 'RangeEnd'

返回的行数或多或少 100 超过十亿,并且 IO 是最小的(如预期的那样)

但是,如果我尝试使用 CROSS APPLY OPENJSON 或 OUTER APPLY OPENJSON 完成查询,则性能一点也不好(提取 100 行需要 1 分钟)

SELECT DocumentKey,  JSON_VALUE(JsonDecompressed, '$.CreditUid') as CreditUid
FROM  [EventSourcing].[EventsTableCompressed] C  
OUTER APPLY OPENJSON (C.JsonDecompressed, '$.MyArrayInsideTheJson') as J
where DocumentKey> 'RangeInit' and DocumentKey< 'RangeEnd'

检查查询计划,我在这两种情况下都有相同的情况,大部分时间都使用集群索引搜索。但是,在 Profiler 工具中,我可以在第二个查询中看到读取和写入的非常大的数字。

我想知道这种行为的原因。似乎 APPLY 正在对所有行执行,而不仅仅是由 where 子句过滤的行。是这样吗?

【问题讨论】:

    标签: json sql-server-2016


    【解决方案1】:

    禁用数据库中的统计可防止该错误。看来,第一次,必须更新统计信息或类似的东西(这就是高容量或写入的原因)。

    【讨论】:

    • 我遇到了类似的问题。您禁用了哪些统计信息(自动创建、自动更新……)?然后您是否只是重新启用它们并神奇地开始工作?谢谢
    猜你喜欢
    • 2017-07-24
    • 2011-10-07
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2013-11-27
    • 2018-02-04
    • 2013-10-30
    • 2016-05-02
    相关资源
    最近更新 更多