এসকিউএল সার্ভার কেন একটি সূচক উপেক্ষা করবে?


16

আমার একটি টেবিল রয়েছে, এতে CustPassMaster16 টি কলাম রয়েছে, যার একটি হ'ল CustNum varchar(8)এবং আমি একটি সূচক তৈরি করেছি IX_dbo_CustPassMaster_CustNum। আমি যখন আমার SELECTবিবৃতি চালাচ্ছি :

SELECT * FROM dbo.CustPassMaster WHERE CustNum = '12345678'

এটি সূচকটিকে সম্পূর্ণ উপেক্ষা করে। এটি আমাকে আরও বিভ্রান্ত করে তোলে কারণ আমার কাছে আরও টেবিল CustDataMasterরয়েছে আরও কলাম (55) যার মধ্যে একটি CustNum varchar(8)। আমি IX_dbo_CustDataMaster_CustNumএই টেবিলের এই কলামে ( ) একটি সূচক তৈরি করেছি এবং ব্যবহারিকভাবে একই কোয়েরিটি ব্যবহার করব:

SELECT * FROM dbo.CustDataMaster WHERE CustNum = '12345678'

এবং এটি আমার তৈরি সূচকটি ব্যবহার করে।

এর পিছনে কি কোনও নির্দিষ্ট যুক্তি রয়েছে? কেন এটি সূচকটি ব্যবহার করবেCustDataMaster , তবে একটিটি নয় CustPassMaster? এটি কি কম কলামের সংখ্যার কারণে?

প্রথম ক্যোয়ারিতে 66 টি সারি দেওয়া হয়। দ্বিতীয়টির জন্য, 1 সারি ফিরে আসে।

এছাড়াও, অতিরিক্ত নোট: CustPassMaster4991 রেকর্ডস রয়েছে, এবং CustDataMasterএর 5376 রেকর্ড রয়েছে। সূচক উপেক্ষা করার পেছনে কি এই যুক্তি হতে পারে? CustPassMasterএছাড়াও সদৃশ রেকর্ড একই আছেCustNum মান রয়েছে। এটি কি অন্য ফ্যাক্টর?

আমি উভয় প্রশ্নের সত্যিকারের বাস্তবায়ন পরিকল্পনার ফলাফলের উপর এই দাবির ভিত্তি করছি।

এখানে ডিডিএল CustPassMaster(অব্যবহৃত সূচকযুক্ত এক):

CREATE TABLE dbo.CustPassMaster(
    [CustNum] [varchar](8) NOT NULL,
    [Username] [char](15) NOT NULL,
    [Password] [char](15) NOT NULL,
    /* more columns here */
    [VBTerminator] [varchar](1) NOT NULL
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_dbo_CustPassMaster_CustNum] ON dbo.CustPassMaster
(
    [CustNum] ASC
) WITH (PAD_INDEX = OFF
    , STATISTICS_NORECOMPUTE = OFF
    , SORT_IN_TEMPDB = OFF
    , DROP_EXISTING = OFF
    , ONLINE = OFF
    , ALLOW_ROW_LOCKS = ON
    , ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

এবং এর জন্য ডিডিএল CustDataMaster(আমি প্রচুর অপ্রাসঙ্গিক ক্ষেত্র বাদ দিয়েছি):

CREATE TABLE dbo.CustDataMaster(
    [CustNum] [varchar](8) NOT NULL,
    /* more columns here */
    [VBTerminator] [varchar](1) NOT NULL
) ON [PRIMARY]

CREATE NONCLUSTERED INDEX [IX_dbo_CustDataMaster_CustNum] ON dbo.CustDataMaster
(
    [CustNum] ASC
)WITH (PAD_INDEX = OFF
    , STATISTICS_NORECOMPUTE = OFF
    , SORT_IN_TEMPDB = OFF
    , DROP_EXISTING = OFF
    , ONLINE = OFF
    , ALLOW_ROW_LOCKS = ON
    , ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

আমার কাছে সেই টেবিলগুলির মধ্যে একটিতে একটি ক্লাস্টার ইনডেক্স নেই, কেবলমাত্র একটি অবিচ্ছিন্ন সূচক।

এই তথ্য উপেক্ষা করুন যে ডেটাটাইপগুলি পুরোপুরি ডেটা সংরক্ষণের সাথে মেলে না। এই ক্ষেত্রগুলি একটি আইবিএম এএস / 400 ডিবি 2 ডাটাবেস থেকে ব্যাকআপ এবং এটি এর জন্য সামঞ্জস্যপূর্ণ ডেটাটাইপগুলি। (আমাকে ঠিক একই প্রশ্নের সাথে এই ব্যাকআপ ডাটাবেসটি অনুসন্ধান করতে সক্ষম হতে হবে এবং সঠিক একই ফলাফল পেতে হবে ।)

এই তথ্যটি শুধুমাত্রSELECT বিবৃতিগুলির জন্য ব্যবহৃত হয় । ব্যাকআপ অ্যাপ্লিকেশন যখন AS / 400 থেকে ডেটা অনুলিপি করছে তখন ব্যতীত আমি এতে কোনও INSERT/ UPDATE/ DELETEবক্তব্য করি না ।


ননক্র্লাস্টার থেকে ক্লাস্টার পর্যন্ত টিপিং পয়েন্ট সম্পর্কে এই নিবন্ধটি পড়ার উপযুক্ত হতে পারে। sqlskills.com/blogs/kimberly/the-tipping-Point-query-answers
মার্ক সিনকিঙ্কন

3
সুতরাং যে পার্থক্য। যদি প্রথম ক্যোয়ারী আপনার সূচকটি ব্যবহার করে, তবে এটি 65 টি লুকআপ করতে হবে। এটি ব্যয়বহুল। দ্বিতীয় ক্যোয়ারিতে কেবল একটি সম্পাদন করতে হবে।
অ্যারন বারট্র্যান্ড

উত্তর:


18

সাধারণত সূচিগুলি এসকিউএল সার্ভার দ্বারা ব্যবহৃত হয় যদি এটি অন্তর্নিহিত টেবিলটি সরাসরি ব্যবহারের চেয়ে সূচীটি ব্যবহার করা আরও সমীচীন মনে করে।

সম্ভবত ব্যয়ভিত্তিক অপটিমাইজার মনে করে যে এটি আসলে প্রশ্নবিদ্ধ সূচকটি ব্যবহার করা আরও ব্যয়বহুল হবে। আপনি দেখতে পাচ্ছেন এটি সূচকটি ব্যবহার করার পরিবর্তে SELECT *, কেবল সহজভাবে করার জন্য SELECT T1Col1

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


3
সুতরাং আমার পক্ষে নির্বাচিত কলামগুলি সীমাবদ্ধ INCLUDEকরে সূচকের দলে অন্তর্ভুক্ত করার জন্য আরও স্পষ্ট এবং সর্বোত্তম সমাধান হবে ?
ডের কোমিশার

1
এটি খুব ভাল একটি বড় পার্থক্য করতে পারে। ক্লোজে ক্যোয়ারী দ্বারা ফিরে আসা সমস্ত কলাম যুক্ত করা INCLUDEএসকিউএল সার্ভারকে সূচকটি ব্যবহার করতে সক্ষম করবে। এটি বলার পরে, আপনি কী অনুকূলিত করার চেষ্টা করছেন? আমার কাছে মনে হয় যদি আপনার টেবিলটির গড় সারির আকার 100 বাইট হয়, তবে 5000 সারিগুলি কেবল 500 কেবিবি ডেটা, এবং এটি কোনও সময় ব্যয় করার উপযুক্ত নাও হতে পারে।
ম্যাক্স ভার্নন

1
গড় সারির আকার 0.30KB Table1এবং এর জন্য 0.53KB Table2। এই সমস্ত ডেটা একটি এএস / 400 (আইবিএম সিস্টেম আমি) থেকে আমদানি করা হয় এবং কোনও পিকে নেই। লোকেরা উল্লেখ করার পরে আমি অ্যাপ্লিকেশনটি বেশিরভাগ সময়ে বেশ ধীর হয়ে যাওয়ার পরে নিজেই সমস্ত সূচক তৈরি করেছি।
ডের কোমিসার

10

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

সম্ভবত ক্লাস্টারযুক্ত সূচি স্ক্যান করার জন্য ব্যয় অনুমান + কী লুক্সগুলি ক্লাস্টারড ইনডেক্স স্ক্যানের জন্য ব্যয় প্রাক্কলন ছাড়িয়ে যায় এবং এজন্য সূচকটি উপেক্ষা করা হয়।

আপনি ব্যবহার করার চেষ্টা করতে পারে set statistics io on এবং তারপরে সূচকটি ব্যবহার করার সময় I / O ব্যয়টি আসলে কম হয় কিনা তা দেখতে একটি সূচক ইঙ্গিত ব্যবহার করতে পারেন। পার্থক্যটি যদি বড় হয় তবে আপনি পরিসংখ্যানগুলি সন্ধান করতে পারেন, যদি সেগুলি পুরানো হয়।

এছাড়াও, যদি আপনার এসকিউএল আসলে ভেরিয়েবল ব্যবহার করে থাকে এবং সঠিক মানগুলি না করে তবে এটি প্যারামিটার স্নিফিংয়ের কারণেও হতে পারে (= পরিকল্পনার তৈরি করতে ব্যবহৃত পূর্ববর্তী মানটি সারণীতে প্রচুর সারি ছিল)।


1

কারণ হতে পারে। অপ্টিমাইজারগুলি ব্যয়ভিত্তিক এবং প্রতিটি নির্বাহের পাথের 'ব্যয়' এর উপর ভিত্তি করে কোন পথটি বেছে নেওয়ার সিদ্ধান্ত নেয়। 'বৃহত্তম' ব্যয়টি ডিস্ক থেকে মেমরির ডেটা পাচ্ছে। যদি অপটিমাইজার গণনা করে যে সূচি এবং ডেটা উভয়ই পড়তে আরও বেশি সময় লাগে তবে এটি সূচকটি এড়িয়ে যাওয়ার সিদ্ধান্ত নিতে পারে। সারিগুলি যত বড় সেগুলি তত বেশি ডিস্ক ব্লকগুলি গ্রহণ করে।

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