এসকিউএল সার্ভার প্রতিটি সারির জন্য একবারে ফাংশনগুলি মূল্যায়ন করে?


9

আমার এই জাতীয় একটি প্রশ্ন আছে:

SELECT col1
FROM   MyTable
WHERE  
    DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) 
       BETWEEN col2 
       AND     col3
;

এটি এর অনুরূপ সম্পাদন পরিকল্পনার একটি সরঞ্জামদণ্ড দেয়:

এক্সিকিউশন টুলটিপ

dateaddপূর্বাভাসের অনাবৃত অংশটি কি ক্যোয়ারীতে প্রতিটি সারির জন্য কার্যকর করা হবে? অথবা এসকিউএল সার্ভার পুরো ক্যোয়ারির জন্য একবার মান গণনা করে?

উত্তর:


13

রানটাইম ধ্রুবক হিসাবে পরিচিত এমন কিছু ফাংশন ধ্রুবক ভাঁজ নামক প্রক্রিয়াটির মধ্য দিয়ে যায় । 'ভাঁজ' করে একটি ধ্রুবক একটি অভিব্যক্তি ক্যোয়ারী এক্সিকিউশনের প্রথম দিকে মূল্যায়ন করা হয়, ফলাফলটি ক্যাশে করা হয় এবং প্রয়োজনের পরিবর্তে ক্যাশে ফলাফল হয়। আপনার ক্যোয়ারিতে DATEADD(dd, 0, DATEDIFF(dd, 0, getdate()))প্রকাশটি, আফাইক, একটি রানটাইম ধ্রুবক এবং সুতরাং প্রতি ক্যোয়ারিতে কেবল একবার একবার ভাঁজ করা হবে এবং মূল্যায়ন করা হবে।

ট্রিভিয়া হিসাবে: যে RAND()ফাংশনটি প্রত্যাখ্যানযোগ্য বলে প্রত্যাশা করা হয় তা আসলে ভাঁজযোগ্য যা কিছু অপ্রত্যাশিত আচরণের দিকে পরিচালিত করে। তবে অন্যান্য, উদাহরণস্বরূপ NEWID(), ভাঁজযোগ্য নয় এবং প্রতি সারি মূল্যায়ন করতে বাধ্য করবে।


2
@ স্টুয়ার্টব্ল্যাকলার - এসকিউএল সার্ভারের ফাংশনগুলি কীভাবে ভাঁজ করা যায় তা এখানে একটি প্রদর্শন রয়েছে GETDATE()
নিক চ্যামাস

2

কার্যকর করার পরিকল্পনাগুলি দুর্দান্ত তবে কখনও কখনও তারা আপনাকে সত্য বলে না tell সুতরাং এখানে পারফরম্যান্স পরীক্ষার ভিত্তিতে একটি প্রমাণ রয়েছে।

(এবং নীচের লাইন - প্রতি সারির জন্য প্রকাশটি মূল্যায়ন করা হচ্ছে না)


;with t(i) as (select 0 union all select i+1 from t where i < 9)
select getdate()-1 as col1,getdate() as col2,getdate() as col3 
into #t 
from t t0,t t1,t t2,t t3,t t4,t t5,t t6,t t7

(100000000 সারি প্রভাবিত)

এটি ওপি ক্যোয়ারী এবং এটি চালাতে প্রায় 12 সেকেন্ড সময় নেয়

SELECT col1
FROM   #t
WHERE  
    DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) 
       BETWEEN col2 
       AND     col3
;

এই ক্যোয়ারী যা কার্যকর করার আগে একটি প্যারামিটারে তারিখটি সঞ্চয় করে, একই সময় প্রায় 12 সেকেন্ড সময় নেয়।

declare @dt datetime = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE())) 

SELECT col1
FROM   #t
WHERE  
      @dt
       BETWEEN col2 
       AND     col3
;

এবং কেবল ফলাফলগুলি যাচাই করতে -
এই ক্যোয়ারী যা কল 1 তে গণনা করে এবং তাই প্রতিটি সারির জন্য অভিব্যক্তিটি পুনরায় গণনা করতে হয় এটি চালাতে 30 সেকেন্ড সময় নেয়।

SELECT col1
FROM   #t
WHERE  
    DATEADD(dd, 0, DATEDIFF(dd, 0, col1)) 
       BETWEEN col2 
       AND     col3
;

সমস্ত মেট্রিকগুলি একই মেট্রিকগুলি সম্পর্কে বার বার প্রদর্শন করে মৃত্যুদণ্ড কার্যকর করা হয়েছিল

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.