টি এসকিউএল-তে CAST ব্যবহার করে পারফরম্যান্স হিট


12

আমাদের কাছে একটি এসকিউএল জেনারেটর রয়েছে যা নির্দিষ্ট ক্ষেত্রগুলির জন্য সাধারণভাবে এসকিউএল শর্তাধীন বিবৃতিগুলি নির্ধারণ করে (যা আলোচনার খাতিরে: আমরা লেবেল করব myField)।

তাহলে myFieldধরনের হয় NVARCHAR, আমরা তাই মত একটি স্ট্রিং বিরুদ্ধে বলেন ক্ষেত্র একটি তুলনামূলক করতে পারেন: myField = 'foo'

তবে এটি ধরণের ক্ষেত্রে কাজ করে না NTEXT। সুতরাং, আমরা একটি ঢালাই সঙ্গে তুলনা করতে হবে: CAST(myField as NVARCHAR(MAX)) = 'foo'। এটি প্রকৃতপক্ষে কাজ করে যদি myFieldটাইপ হয় NVARCHARবা হয় NTEXT

একটি ক্ষেত্র যে উপর উপরোক্ত ঢালাই করছেন কর্মক্ষমতা হিট কি ইতিমধ্যে ধরনের NVARCHAR? আমার আশা হ'ল এসকিউএল সার্ভারটি myFieldইতিমধ্যে টাইপযুক্ত NVARCHAR(কার্যকরভাবে CASTকোনও অপশনে রূপান্তরিত করা) গতিশীলরূপে স্বীকৃতি দিতে যথেষ্ট স্মার্ট ।


এই প্রশ্নটি যে কেউ খুঁজে পেয়েছে তার জন্য একটি দ্রুত নোট: এনটিএসএক্স (এবং পাঠ এবং চিত্র) আনুষ্ঠানিকভাবে হ্রাস করা হয়েছে এবং এসকিউএল সার্ভারের ভবিষ্যতের সংস্করণে সরানোর কারণে (যদিও আইআইআরসি তারা এখনও এসকিউএল 1014 এ কাজ করে), সুতরাং আপনার উচিত এনভিচারারআর (ম্যাক্স) (বা পরিবর্তার (ম্যাক্স) বা ভার্বিনারি (ম্যাক্স)) পরিবর্তে। এই উদাহরণে একটি এনভিচারচার (ম্যাক্স) এর সাথে এনটিএসএক্স কলামটি প্রতিস্থাপন করা কাস্টের প্রয়োজনীয়তা সরিয়ে ফেলবে কারণ সেই ধরণের সাথে সরাসরি তুলনা করা যেতে পারে এবং এখানে এবং অন্য কোথাও অন্যান্য সম্ভাব্য দক্ষতা লাভ রয়েছে। দুর্ভাগ্যক্রমে আপনি একটি * (ম্যাক্স) কলামটি সূচী করতে পারবেন না তবে আপনি কোনও পাঠ্য / এনটিএক্স্টও পারেন না।
ডেভিড স্পিললেট

উত্তর:


12

যদি কলামটির castালাই একই ডেটাটাইপ এবং দৈর্ঘ্যের সাথে থাকে এবং অনুসন্ধানের প্রস্তাবটি আক্ষরিক হয় তবে এটি অবশ্যই এটিকে অবহেলা করে দেখায় বা এটিকে কোনও অপ-বিকল্প হিসাবে বিবেচনা করে না এবং কোনও সূচক সমতার দিকে চেয়ে থাকে।

Seek Keys[1]: Prefix: [tempdb].[dbo].[#test].name = Scalar Operator(N'rpc')

কলামের theালাই যদি একই ডেটাটাইপ হয় তবে এর চেয়ে বেশি দৈর্ঘ্য এবং সিক হুংকার একটি স্ট্রিং আক্ষরিক হয় এটি সূচক স্ক্যানের কারণ হয়ে থাকে। এটি অবশ্যই এড়ানো উচিত।

যদি কলামের castালাই একই ডেটাটাইপ এবং একই বা বৃহত্তর দৈর্ঘ্যের হয় এবং সিক হু হু হু হু হু ইন্ডিয়ান ভেরিয়েবল হয় এটি এক্সিকিউশন প্ল্যানে একটি কম্পিউট স্কেলার অপারেটর যুক্ত করে। এটি কল করে GetRangeThroughConvertএবং একটি পরিসীমা আউটপুট দেয়।

এই পরিসরটি একটি সূচী অনুসন্ধান করতে ব্যবহৃত হয় এবং বেশ দক্ষ বলে মনে হয়

Seek Keys[1]: 
Start: [tempdb].[dbo].[#test].name > Scalar Operator([Expr1006]), 
End: [tempdb].[dbo].[#test].name < Scalar Operator([Expr1007])

পরীক্ষার কোড

SELECT *
 INTO #test
  FROM [master].[dbo].[spt_values]

CREATE NONCLUSTERED INDEX [ixname] ON #test
(
    [name] ASC
)

DECLARE @name NVARCHAR(MAX)

SET @name = 'rpc'

SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(35))= @name --Cast the same and local variable

SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(MAX))=@name --Cast to longer and local variable

SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(35))='rpc' --Cast the same and literal

SELECT name
FROM #test
WHERE CAST(name AS NVARCHAR(MAX))='rpc' --Cast to longer and literal

6

সাধারণভাবে, CASTউইল পারফরম্যান্সকে হত্যার কারণ এটি মার্টিন স্মিথের শেষ উদাহরণ হিসাবে দেখায় সূচকের সন্ধানের যে কোনও ব্যবহার অকার্যকর করে দেয়। nvarchar(max)আলাদা দৈর্ঘ্যে বা কাস্টিংয়ের অর্থ একটি ভিন্ন ডেটা ধরণের: আসলে এটি সমস্ত nvarcharঅপ্রাসঙ্গিক।

তার ওপরে, ডান হাতের ডেটটাইপটি তুলনা করার বিষয়টিও গুরুত্বপূর্ণ। যদি এটি স্থানীয় দৈর্ঘ্যের ভিন্ন দৈর্ঘ্যের প্যারামিটার হয় তবে এক দিকটি CAST2 ডেটাটাইপের বৃহত্তর ( স্পষ্টতই ডেটাটাইপের অগ্রাধিকার দেখুন ) প্রচ্ছন্ন হবে

মূলত, যদি আপনার CASTকাছে nvarchar(max)এটির একটি জেনারেল থাকে তবে এটি জিনিসগুলিকে উচ্চারণ করবে। আমি সমস্ত ntextযোগ করার আগে ব্যবহারের স্থিরতা বিবেচনা করব CAST

রূপান্তরটি কোয়েরি পরিকল্পনায় নাও দেখাতে পারে। দেখুন পল হোয়াইট এর ব্লগ নিবন্ধ


2

কেবল একটি নোট, ডেটক্রিটযুক্ত তারিখের সময় এই জাতীয় কাস্টিং

 Cast (Datecreated as date) = cast(@MydatetimeValue as date)

সূচকের উপস্থিতি থাকলে এসকিউএল এর সূচকগুলি ব্যবহার করার ক্ষমতা ভঙ্গ করে না এবং যদি তা বিদ্যমান না থাকে তবে একটি অনুপস্থিত সূচকে লগ ইন করতে পারে।

একইভাবে, যখন থেকে কাস্ট intকরার tinyintবা bigintকরার intইত্যাদি ঢালাই ফাংশন এসকিউএল অপ্টিমাইজার জানে যে ঢালাই অপারেশন 2 তুলনীয় datatypes সাজানোর ক্রম পরিবর্তন করে না ইনডেক্স ব্যবহার থেকে থামবে না।

অ্যাডভেঞ্চারওয়ার্কস 2008 আর 2 ব্যবহার করে আপনি চালাতে এবং আসল পরিকল্পনাটি দেখতে পারেন এমন একগুচ্ছ পরীক্ষাগুলি এখানে রয়েছে

select count(*) from Sales.SalesOrderDetail where SalesOrderID = 8 --1
select top 10 * from Sales.SalesOrderDetail where cast(SalesOrderID as tinyint) = 8  --2
select top 10 * from Sales.SalesOrderDetail where cast(SalesOrderID as bigint) = 8  --3
select top 10 SalesOrderID from Sales.SalesOrderDetail where cast(ModifiedDate  as date) = '19780322' --4
select top 10 SalesOrderID from Sales.SalesOrderDetail where convert(date,ModifiedDate) = '19780322'  --5
select top 10 SalesOrderID from Sales.SalesOrderDetail where cast(ModifiedDate as varchar(20)) = '1978'  --6 -- THIS WILL NOT USE INDEX
select  SalesOrderID from Sales.SalesOrderDetail where cast(ModifiedDate  as date) between '19780101' and '19780109'  --7

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