In my SQL Server 2016+, I have a table with a json column, the json column has this format:
{
"$type": "Sample.Product, Sample",
"Name": "sample",
"Id": "12345",
"Policies": {
"$type": "System.Collections.Generic.List`1[[Sample.Policy, Sample]], mscorlib",
"$values": [
{
"$type": "Sample.ListPricingPolicy, Sample",
"Prices": {
"$type": "System.Collections.Generic.List`1[[Sample.Money, Sample]], mscorlib",
"$values": [
{
"$type": "Sample.Money, Sample",
"CurrencyCode": "USD",
"Amount": 49.9900
}
]
},
"PolicyId": "af5617ad5a2146a981a5db46ecae60be",
"Models": {
"$type": "System.Collections.Generic.List`1[[Sample.Model, Sample]], mscorlib",
"$values": []
}
},
{
"$type": "Sample.PriceCardPolicy, Sample",
"PriceCardName": "PriceCard-12345",
"PolicyId": "c34c61051d59459fb14e057bead2d128",
"Models": {
"$type": "System.Collections.Generic.List`1[[Sample.Model, Sample]], mscorlib",
"$values": []
}
}
]
}
}
In above data:
- the main type may be not
Sample.Product, Sample
, Policies.$values
is a generic list, can be any type ofPolicy
PriceCardPolicy
may not exist in some json data
I need to filter all those products that have PriceCardPolicy
.
My current SQL is:
SELECT s.*
FROM dbo.product s
WHERE
json_value(s.Data, '$."$type"') = 'Sample.Product, Sample'
AND NOT EXISTS -- filter all those who have `PriceCardPolicy`
(
SELECT e.*
FROM dbo.product e
CROSS apply Openjson(e.Data, '$.Policies."$values"') WITH(policytype nvarchar(max) '$."$type"') policies
WHERE
json_value(e.Data, '$."$type"') = 'Sample.Product, Sample'
AND policies.policytype = 'Sample.PriceCardPolicy, Sample'
AND s.id = e.id)
But its performance is really bad when data grows up, like 500K rows. how can I improve this?
For example:
There are 500k rows, but only 5 rows have no PriceCardPolicy
. I need to find out those 5 rows.
I am not able to do any change from database, I can only focus on improving this SQL. Thx.