【发布时间】:2019-09-09 14:11:37
【问题描述】:
SQL Server 2017。
表 OrderData 具有存储 JSON 的列 DataProperties。 JSON 示例存储在那里:
{
"Input": {
"OrderId": "abc",
"Data": [
{
"Key": "Files",
"Value": [
"test.txt",
"whatever.jpg"
]
},
{
"Key": "Other",
"Value": [
"a"
]
}
]
}
}
所以,它是一个带有 Input 对象的对象,它具有 KVP 的 Data 数组 - 充满了带有 Key 字符串和 Value 字符串数组的对象。
我的问题 - 我需要根据示例 JSON 中的文件中的值查询行 - 与 %text% 匹配的简单 LIKE。
此查询有效:
SELECT TOP 10 *
FROM OrderData CROSS APPLY OPENJSON(DataProperties,'$.Input.Data') dat
WHERE JSON_VALUE(dat.value, '$.Key') = 'Files' and dat.[key] = 0
AND JSON_QUERY(dat.value, '$.Value') LIKE '%2%'
问题是这个查询很慢,这不足为奇。
如何让它更快?
- 我无法使用 JSON_VALUE 创建计算列,因为我需要在数组中进行过滤。
- 我无法在“$.Input.Data”或“$.Input.Data[0].Values”上使用 JSON_QUERY 创建计算列 - 因为我需要在此数组中使用
Key == "Files"指定特定数组项。
我已经搜索过,但您似乎无法创建也过滤数据的计算列,就像这次尝试一样:
ALTER TABLE OrderData
ADD aaaTest AS (select JSON_QUERY(dat.value, '$.Value')
OPENJSON(DataProperties,'$.Input.Data') dat
WHERE JSON_VALUE(dat.value, '$.Key') = 'Files' and dat.[key] = 0 );
错误:Subqueries are not allowed in this context. Only scalar expressions are allowed.
我有什么选择?
- 添加带有索引的文件列并使用插入/更新时填充此列的 INSERT/UPDATE 触发器?
- 创建一个“计算”该列的视图?无法添加索引,还是会很慢
到目前为止,只有选项 1. 有一些优点,但我不喜欢触发器,也许还有其他选项?
【问题讨论】:
-
是的,您希望在插入期间解析 JSON,并将这些键/值对存储到正确的架构和索引表中,以提高查询效率。
-
我希望这是一个错字,我们曾经看到过
"Value"(单数)和一次"Values"(复数)。两者都命名一个值数组... -
是的,一个错字,已修复,在我的情况下,它是单数
Value,带有值数组。 -
@Lars,好吧......所以你必须在我的回答中纠正这个;-)
-
@Jon 数字。无法更改 JSON 以适应计算列,即将 Files 数组移动到 Input.Data.Files 属性,必须使用触发器。
标签: json tsql sql-server-2017