【发布时间】: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