কোন এসকিউএল স্টেটমেন্টকে ব্যর্থ করে তোলে?


252

সংজ্ঞা অনুসারে (কমপক্ষে আমি যা দেখেছি তা থেকে) সার্গেবলের অর্থ একটি ক্যোয়ারী ক্যোয়ারীটি ব্যবহার করে এমন এক্সিকিউশন প্ল্যানটিকে অনুকূল করে তোলে যা ক্যোয়ারী ব্যবহার করে execution আমি উত্তরগুলি সন্ধান করার চেষ্টা করেছি, তবে বিষয়টিতে তেমন কিছু নেই বলে মনে হচ্ছে। সুতরাং প্রশ্নটি হল, একটি এসকিউএল কোয়েরিটি सार्জকেবল করে বা কী করে না? যে কোনও ডকুমেন্টেশন প্রশংসিত হবে।

রেফারেন্সের জন্য: SARGable


58
"সরগেবল" এর জন্য +1। এটি আজকের দিনের আমার কথা। :-p
বিফ্রি

1
আমি অ্যাডামের জবাবটি যোগ করতে পারি, তথ্যের পর্বতগুলি প্রতিটি ক্ষেত্রে প্রতিটি ডিবি ইঞ্জিনের জন্য অত্যন্ত নির্দিষ্ট।
হোয়াগি

30
এসআরজি = অনুসন্ধান এরগুমেন্ট। মজার বিষয় হ'ল: জার্মানিতে "এসএআরজি" এর অর্থ "কফিন", তাই লোকেরা সারগাবল সম্পর্কে কথা বলার সময় আমাকে সর্বদা হাসি দিতে হবে - কফিনে রাখতে সক্ষম? :-)
marc_s

ব্যস্ততা আপনার পরিবেশের উপর নির্ভর করে। মাইএসকিউএলএস এখানে নথিভুক্ত করা হয়েছে: dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
ফ্র্যাঙ্ক ফার্মার

"অনুসন্ধানের টেবিলগুলি" এর পরিবর্তে ফ্রি-টেক্সট ক্ষেত্রগুলি থাকা একটি কোয়েরিটিকে সারগ্যাবল করার স্পিরিটের বিরুদ্ধে যায়। ব্যবহারকারীরা ফ্রি-টেক্সট (উদাহরণস্বরূপ শহরের নাম) প্রবেশের সময় স্টাফগুলি ভুল বানান করে থাকে, যেখানে লকিং-টেবিলগুলি ব্যবহারকারীদের একটি সঠিক বানানযুক্ত এন্ট্রি বেছে নিতে বাধ্য করে। সামান্য অতিরিক্ত সমস্যার জন্য মূল্যহীন, কারণ এটি প্রাক্কলনে '% ...%' পছন্দ করার পরিবর্তে যথাযথভাবে সূচকযুক্ত করা যেতে পারে।
বিপরীত প্রকৌশলী

উত্তর:


256

যে প্রশ্নটি অ-সরগাব্য করে তোলে এমন সর্বাধিক সাধারণ জিনিসটি হ'ল ধারাটিতে কোনও ফাংশনের অভ্যন্তরে কোনও ক্ষেত্র অন্তর্ভুক্ত করা :

SELECT ... FROM ...
WHERE Year(myDate) = 2008

এসকিউএল অপ্টিমাইজারটি মাইডেটে কোনও সূচক ব্যবহার করতে পারে না, এমনকি যদি এটি বিদ্যমান থাকে। এটি টেবিলের প্রতিটি সারি জন্য আক্ষরিকভাবে এই ফাংশনটি মূল্যায়ন করতে হবে। ব্যবহার করা আরও ভাল:

WHERE myDate >= '01-01-2008' AND myDate < '01-01-2009'

আরও কয়েকটি উদাহরণ:

Bad: Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones'
Fixed: Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))

Bad: Select ... WHERE SUBSTRING(DealerName,4) = 'Ford'
Fixed: Select ... WHERE DealerName Like 'Ford%'

Bad: Select ... WHERE DateDiff(mm,OrderDate,GetDate()) >= 30
Fixed: Select ... WHERE OrderDate < DateAdd(mm,-30,GetDate()) 

7
ভিতরে কোনও ক্রিয়াকলাপ অন্তর্ভুক্ত করার GROUP BYকারণে কোনও ক্যোয়ারী অ-সরজযোগ্য হয়ে উঠবে?
মাইক বেইলি

1
কিছু ডাটাবেস ইঞ্জিন (ওরাকল, পোস্টগ্রিয় এসকিউএল) এক্সপ্রেশনগুলিতে সূচকগুলি সমর্থন করে, ড্যান্টচা জানেন?
ক্রেগ

3
এর আরও ভাল সংস্করণ WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))হবে SELECT... FROM ... WHERE FullName = 'Ed Jones' UNION SELECT...FROM...WHERE FullName IS NULL? আমাকে একবার একটি অপ্টিমাইজেশান লোক বলেছিল যে ওআর ব্যবহার করে যেখানে ধারাটি আনসার্গ করতে পারে না ..?
হাই প্লেন গ্রিফটার

2
@ হাইপ্লেইনস গ্রিফটারে আপনাকে এই ক্যোয়ারিতে ইউনিয়ন সমস্ত ব্যবহার করা উচিত - ইউনিয়নের একটি অন্তর্নিহিত স্বতন্ত্র বৈশিষ্ট্য রয়েছে, যা আপনাকে যখন পারস্পরিক একচেটিয়া ডেটাসেটগুলি করতে হবে তখন তার চেয়ে অনেক বেশি ব্যয়বহুল তৈরি করে
ডেভিন ল্যামোথ

1
@ ব্র্যাডিসি এমএসএসকিউএল ২০১ 2016-তে Select ... WHERE isNull(FullName,'Ed Jones') = 'Ed Jones'এবং এর মধ্যে কার্যকর করার পরিকল্পনার কোনও পার্থক্য নেই Select ... WHERE ((FullName = 'Ed Jones') OR (FullName IS NULL))। তারা উভয়ই ফুলনেমে সূচকটি ব্যবহার করে এবং একটি সূচি সন্ধান করে।
সিইজিআরডি

79

এটি করবেন না:

WHERE Field LIKE '%blah%'

এটি একটি সারণী / সূচক স্ক্যানের কারণ, কারণ LIKE মান একটি ওয়াইল্ডকার্ড অক্ষর দিয়ে শুরু হয়।

এটি করবেন না:

WHERE FUNCTION(Field) = 'BLAH'

এটি একটি সারণী / সূচক স্ক্যানের কারণ।

ডাটাবেস সার্ভারকে সারণির প্রতিটি সারির বিপরীতে FUNCTION () মূল্যায়ন করতে হবে এবং তারপরে এটি 'BLAH' এর সাথে তুলনা করতে হবে।

যদি সম্ভব হয় তবে এটি বিপরীতে করুন:

WHERE Field = INVERSE_FUNCTION('BLAH')

এটি প্যারামিটারের বিরুদ্ধে একবার INVERSE_FUNCTION () চালাবে এবং তবুও সূচকটি ব্যবহারের অনুমতি দেবে।


5
ফাংশনটি উল্টিয়ে দেওয়ার সাথে আপনার পরামর্শটি কেবল তখনই কাজ করবে যখন ফাংশনটি রাউন্ড-ট্রিপস ডেটা (যার অর্থ f (f (n)) = n)।
অ্যাডাম রবিনসন

5
সত্য। আমি INVERSE_FUNCTION যোগ করার বিষয়টি বিবেচনা করেছি কিন্তু বিভ্রান্ত হতে চাই না। আমি এটা পরিবর্তন করব।
সৈকত

9

এই উত্তরে আমি ধরে নিই যে ডাটাবেসে যথেষ্ট আচ্ছাদন সূচক রয়েছে। এই বিষয় সম্পর্কে যথেষ্ট প্রশ্ন আছে ।

সম্পর্কিত প্রশ্নের সূচকগুলির টিপিং পয়েন্ট দ্বারা অনেক সময় অনুসন্ধানের ব্যস্ততা নির্ধারণ করা হয়। টিপিং পয়েন্টটি একটি টেবিলের সাথে যোগ হতে গিয়ে অন্য টেস্টে ফলাফল সেট করার সময় একটি সূচক চাওয়া এবং স্ক্যান করার মধ্যে পার্থক্যকে সংজ্ঞায়িত করে। একটি সন্ধান অবশ্যই পুরো টেবিলটি স্ক্যান করার চেয়ে অনেক দ্রুত, তবে আপনাকে যখন অনেকগুলি সারি সন্ধান করতে হয়, তখন একটি স্ক্যান আরও অর্থবোধ করতে পারে।

অন্যান্য বিষয়গুলির মধ্যে একটি এসকিউএল স্টেটমেন্টটি আরও ব্যস্ত থাকে যখন অপ্টিমাইজারটি আশা করে যে একটি সারণীর ফলস্বরূপ সারিগুলির সংখ্যা পরবর্তী সারণীতে সম্ভাব্য সূচকের টিপিং পয়েন্টের চেয়ে কম হবে।

আপনি এখানে একটি বিস্তারিত পোস্ট এবং উদাহরণ খুঁজে পেতে পারেন ।


4

কোনও ক্রিয়াকলাপকে ব্যয়যোগ্য হিসাবে বিবেচনা করার জন্য, এটি কেবলমাত্র বিদ্যমান সূচকটি ব্যবহার করতে সক্ষম হবে তা যথেষ্ট নয় not উপরের উদাহরণে, যেখানে ধারাটিতে কোনও সূচকযুক্ত কলামের বিরুদ্ধে ফাংশন কল যুক্ত করা সুনির্দিষ্টভাবে সংজ্ঞায়িত সূচকের কিছুটা সুবিধা নেবে। এটি "স্ক্যান" ওরফে সেই কলাম (সূচী) থেকে সমস্ত মানগুলি পুনরুদ্ধার করবে এবং তারপরে প্রদত্ত ফিল্টার মানের সাথে মেলে না এমনগুলি মুছে ফেলবে। সারি সংখ্যক সারিযুক্ত টেবিলগুলির জন্য এটি এখনও যথেষ্ট দক্ষ নয়। স্যারগ্যাবিলিটিটি আসলে যা সংজ্ঞায়িত করে তা হ'ল বাইনারি অনুসন্ধান পদ্ধতিটি বাছাই করা আইটেমির অ্যারেতে অর্ধ-সেট নির্মূলকরণের উপর নির্ভর করে বি-ট্রি সূচককে অতিক্রম করার ক্যোরিয়াস ক্ষমতা। এসকিউএল এ, এটি "সূচক সন্ধান" হিসাবে কার্যকরকরণ পরিকল্পনায় প্রদর্শিত হবে।

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