আমার কাছে একটি ক্যোয়ারী রয়েছে যা প্যারামিটার হিসাবে একটি জসন স্ট্রিং নেয়। জসন হ'ল অক্ষাংশ, দ্রাঘিমাংশের জোড়গুলির একটি অ্যারে। একটি উদাহরণ ইনপুট নিম্নলিখিত হতে পারে।
declare @json nvarchar(max)= N'[[40.7592024,-73.9771259],[40.7126492,-74.0120867]
,[41.8662374,-87.6908788],[37.784873,-122.4056546]]';
এটি এমন একটি টিভিএফ কল করে যা ভৌগলিক পয়েন্টের কাছাকাছি 1,3,5,10 মাইল দূরত্বে পিওআই এর সংখ্যা গণনা করে।
create or alter function [dbo].[fn_poi_in_dist](@geo geography)
returns table
with schemabinding as
return
select count_1 = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 1,1,0e))
,count_3 = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 3,1,0e))
,count_5 = sum(iif(LatLong.STDistance(@geo) <= 1609.344e * 5,1,0e))
,count_10 = count(*)
from dbo.point_of_interest
where LatLong.STDistance(@geo) <= 1609.344e * 10
জসন ক্যোয়ারির উদ্দেশ্যটি হ'ল এই ফাংশনটিকে বাল্ক কল করা call যদি আমি এটির মতো বলি তবে পারফরম্যান্সটি খুব দুর্বল মাত্র 4 পয়েন্টের জন্য 10 সেকেন্ড সময় নিয়েছে:
select row=[key]
,count_1
,count_3
,count_5
,count_10
from openjson(@json)
cross apply dbo.fn_poi_in_dist(
geography::Point(
convert(float,json_value(value,'$[0]'))
,convert(float,json_value(value,'$[1]'))
,4326))
পরিকল্পনা = https://www.brentozar.com/pastetheplan/?id=HJDCYd_o4
যাইহোক, একটি উত্পন্ন টেবিলের মধ্যে ভূগোলের নির্মাণকে সরিয়ে দেওয়ার কারণে প্রায় 1 সেকেন্ডে কোয়েরিটি সম্পূর্ণ করে নাটকীয়ভাবে উন্নতি হয় causes
select row=[key]
,count_1
,count_3
,count_5
,count_10
from (
select [key]
,geo = geography::Point(
convert(float,json_value(value,'$[0]'))
,convert(float,json_value(value,'$[1]'))
,4326)
from openjson(@json)
) a
cross apply dbo.fn_poi_in_dist(geo)
পরিকল্পনা = https://www.brentozar.com/pastetheplan/?id=HkSS5_OoE
পরিকল্পনাগুলি কার্যত অভিন্ন দেখায়। উভয়ই সমান্তরালতা ব্যবহার করে না এবং উভয়ই স্থানিক সূচক ব্যবহার করে। ধীর পরিকল্পনায় অতিরিক্ত অলস স্পুল রয়েছে যা আমি ইঙ্গিতটি দিয়ে শেষ করতে পারি option(no_performance_spool)
। কিন্তু ক্যোয়ারির পারফরম্যান্স পরিবর্তন হয় না। এটি এখনও অনেক ধীর থাকে remains
একটি ব্যাচে যুক্ত ইঙ্গিত সহ উভয়কে চালানো উভয় প্রশ্নের সমান পরিমাণে ওজন করবে।
SQL সার্ভার সংস্করণ = মাইক্রোসফ্ট এসকিউএল সার্ভার 2016 (এসপি 1-সিইউ 7-জিডিআর) (KB4057119) - 13.0.4466.4 (এক্স 64)
তাহলে আমার প্রশ্ন হল কেন এই ব্যাপারটি? আমি কীভাবে জানতে পারি যখন আমার কোনও উত্পন্ন টেবিলের অভ্যন্তরে মানগুলি গণনা করা উচিত বা না?
point_of_interest
টেবিলে 358306 লজিক্যাল রিড করেন , উভয়ই 4602 বার সূচকটি স্ক্যান করে এবং উভয়ই একটি ওয়ার্কটেবল এবং ওয়ার্কফাইল উত্পন্ন করে। অনুমানকারী বিশ্বাস করেন যে এই পরিকল্পনাগুলি অভিন্ন তবে কর্মক্ষমতা অন্যথায় বলে says
|LatLong.Lat - @geo.Lat| + |LatLong.Long - @geo.Long| < n
আরও বেশি জটিল করার আগে মানটি তাদের জন্য প্রথমে ফিল্টার করুন sqrt((LatLong.Lat - @geo.Lat)^2 + (LatLong.Long - @geo.Long)^2)
। এবং আরও ভাল, প্রথমে উপরের এবং নিম্ন সীমা গণনা করুন, তারপরে LatLong.Lat > @geoLatLowerBound && LatLong.Lat < @geoLatUpperBound && LatLong.Long > @geoLongLowerBound && LatLong.Long < @geoLongUpperBound
। (এটি সিউডোকোড, যথাযথভাবে মানিয়ে নিন))