আইএন () ব্যবহার করে ক্যোয়ারির পারফরম্যান্স উন্নত করুন


14

আমার নিম্নলিখিত এসকিউএল কোয়েরি রয়েছে:

SELECT
  Event.ID,
  Event.IATA,
  Device.Name,
  EventType.Description,
  Event.Data1,
  Event.Data2
  Event.PLCTimeStamp,
  Event.EventTypeID
FROM
  Event
INNER JOIN EventType ON EventType.ID = Event.EventTypeID
INNER JOIN Device ON Device.ID = Event.DeviceID
WHERE
  Event.EventTypeID IN (3, 30, 40, 41, 42, 46, 49, 50)
  AND Event.PLCTimeStamp BETWEEN '2011-01-28' AND '2011-01-29'
  AND Event.IATA LIKE '%0005836217%'
ORDER BY Event.ID;

Eventকলামটির জন্য আমার টেবিলে একটি সূচকও রয়েছে TimeStamp। আমার বোধগম্যতা হল যে এই সূচীটি IN()বিবৃতিটির কারণে ব্যবহার করা হয়নি । সুতরাং আমার প্রশ্নটি কি IN()এই কোয়েরিটির গতি বাড়ানোর জন্য এই বিশেষ বিবৃতিটির জন্য একটি সূচক তৈরি করার কোনও উপায় আছে ?

আমি Event.EventTypeID IN (2, 5, 7, 8, 9, 14)সূচকটির জন্য ফিল্টার হিসাবে যুক্ত করার চেষ্টাও করেছি TimeStamp, তবে কার্যকর করার পরিকল্পনার দিকে তাকালে এটি এই সূচকটি ব্যবহার করে না বলে মনে হয়। এ সম্পর্কে কোনও পরামর্শ বা অন্তর্দৃষ্টি প্রশংসিত হবে।

নীচে গ্রাফিকাল পরিকল্পনা:

হত্যা পরিকল্পনা

আর এখানে .sqlplan ফাইলের একটি লিঙ্ক


আমরাও ফাঁসির পরিকল্পনাটি দেখতে পারি? :)
dezso

1
এবং দয়া করে .sqlplan এক্সটেনশন সহ প্রকৃত বাস্তবায়ন পরিকল্পনা (আনুমানিক নয়) পোস্ট করুন। বেশিরভাগ লোকেরা কেবল গ্রাফিকাল পরিকল্পনার একটি স্ক্রিন শট পোস্ট করতে চান এবং এটি খুব কম কার্যকর।
অ্যারন বার্ট্র্যান্ড

ঠিক আছে আমি কার্যকর করার পরিকল্পনা যুক্ত করেছি পাশাপাশি এসকিউএল কোয়েরি আপডেট করেছি।
SandersKY

@ স্যান্ডার্সকিওয়াই প্রশ্নের সাথে সম্পর্কিত সমস্ত কিছু একই সাইটে রাখার জন্য .sqlplan ফাইলটি ইনলাইন করা ভাল।
ট্রাইগভে লগস্টেল

1
@ টিরিগভিস - পোস্টগুলিতে দৈর্ঘ্যের সীমাবদ্ধতার কারণে এটি প্রায়শই সম্ভব হত না। লজ্জাজনক স্ট্যাক এক্সচেঞ্জ অভ্যন্তরীণভাবে পোস্ট সংযুক্তিগুলি হোস্টিং সমর্থন করে না।
মার্টিন স্মিথ

উত্তর:


18

নিম্নলিখিত সাধারণ ফর্মের দেওয়া সারণী:

CREATE TABLE Device 
(
    ID integer PRIMARY KEY
);

CREATE TABLE EventType
(
    ID integer PRIMARY KEY, 
    Name nvarchar(50) NOT NULL
);

CREATE TABLE [Event]
(
    ID integer PRIMARY KEY, 
    [TimeStamp] datetime NOT NULL, 
    EventTypeID integer NOT NULL REFERENCES EventType, 
    DeviceID integer NOT NULL REFERENCES Device
);

নিম্নলিখিত সূচক দরকারী:

CREATE INDEX f1 
ON [Event] ([TimeStamp], EventTypeID) 
INCLUDE (DeviceID)
WHERE EventTypeID IN (2, 5, 7, 8, 9, 14);

প্রশ্নের জন্য:

SELECT
  [Event].ID,
  [Event].[TimeStamp],
  EventType.Name,
  Device.ID
FROM
  [Event]
INNER JOIN EventType ON EventType.ID = [Event].EventTypeID
INNER JOIN Device ON Device.ID = [Event].DeviceID
WHERE
  [Event].[TimeStamp] BETWEEN '2011-01-28' AND '2011-01-29'
  AND Event.EventTypeID IN (2, 5, 7, 8, 9, 14);

ফিল্টারটি ANDধারাটির প্রয়োজনীয়তা পূরণ করে , সূচকের প্রথম কীটি [TimeStamp]ফিল্টারগুলির জন্য সন্ধান করার অনুমতি দেয় EventTypeIDsএবং DeviceIDকলামটি সহ সূচিটি আচ্ছাদন করে তোলে (কারণ টেবিলে DeviceIDযোগদানের জন্য প্রয়োজনীয় Device)।

সমাপ্ত পরিকল্পনা

সূচকের দ্বিতীয় কী - EventTypeIDকঠোরভাবে প্রয়োজন হয় না (এটি একটি INCLUDEdকলামও হতে পারে ); আমি এটা অন্তর্ভুক্ত করেছেন কী তে জন্য এখানে বিবৃত কারণে । সাধারণভাবে, আমি INCLUDEএকটি ফিল্টার সূচক WHEREধারা থেকে কমপক্ষে কলামগুলিতে লোকদের পরামর্শ দিই ।


প্রশ্নের আপডেট হওয়া ক্যোয়ারী এবং কার্যনির্বাহী পরিকল্পনার ভিত্তিতে আমি সম্মত হই যে এসএসএমএস দ্বারা প্রস্তাবিত আরও সাধারণ সূচক সম্ভবত এখানে আরও ভাল পছন্দ, যদি না EventTypeIDsঅ্যারন তার উত্তরে উল্লেখ না করে তবে ফিল্টারগুলির তালিকা স্থির না হয়:

CREATE TABLE Device 
(
    ID integer PRIMARY KEY,
    Name nvarchar(50) NOT NULL UNIQUE
);

CREATE TABLE EventType
(
    ID integer PRIMARY KEY, 
    Name nvarchar(20) NOT NULL UNIQUE,
    [Description] nvarchar(100) NOT NULL
);

CREATE TABLE [Event]
(
    ID integer PRIMARY KEY, 
    PLCTimeStamp datetime NOT NULL,
    EventTypeID integer NOT NULL REFERENCES EventType, 
    DeviceID integer NOT NULL REFERENCES Device,
    IATA varchar(50) NOT NULL,
    Data1 integer NULL,
    Data2 integer NULL,
);

প্রস্তাবিত সূচক (উপযুক্ত হলে এটি অনন্য ঘোষণা করুন):

CREATE UNIQUE INDEX uq1
ON [Event]
    (EventTypeID, PLCTimeStamp)
INCLUDE 
    (DeviceID, IATA, Data1, Data2, ID);

সম্পাদন পরিকল্পনা থেকে কার্ডিনালিটির তথ্য (অপ্রকাশিত সিনট্যাক্স, উত্পাদন সিস্টেমে ব্যবহার করবেন না):

UPDATE STATISTICS dbo.Event WITH ROWCOUNT = 4042700, PAGECOUNT = 400000;
UPDATE STATISTICS dbo.EventType WITH ROWCOUNT = 22, PAGECOUNT = 1;
UPDATE STATISTICS dbo.Device WITH ROWCOUNT = 2806, PAGECOUNT = 28;

আপডেট করা ক্যোয়ারী ( টেবিলের INজন্য তালিকার পুনরাবৃত্তি EventTypeএই নির্দিষ্ট ক্ষেত্রেটি অপ্টিমাইজারকে সহায়তা করে):

SELECT
  Event.ID,
  Event.IATA,
  Device.Name,
  EventType.Description,
  Event.Data1,
  Event.Data2,
  Event.PLCTimeStamp,
  Event.EventTypeID
FROM
  Event
INNER JOIN EventType ON EventType.ID = Event.EventTypeID
INNER JOIN Device ON Device.ID = Event.DeviceID
WHERE
  Event.EventTypeID IN (3, 30, 40, 41, 42, 46, 49, 50)
  AND EventType.ID IN (3, 30, 40, 41, 42, 46, 49, 50)
  AND Event.PLCTimeStamp BETWEEN '2011-01-28' AND '2011-01-29'
  AND Event.IATA LIKE '%0005836217%'
ORDER BY Event.ID;

আনুমানিক বাস্তবায়ন পরিকল্পনা:

দ্বিতীয় পরিকল্পনা

আপনি যে পরিকল্পনাটি পাবেন তা সম্ভবত ভিন্ন হবে কারণ আমি অনুমান করা পরিসংখ্যান ব্যবহার করছি। সাধারণ বিষয়টি হ'ল অপটিমাইজারটিকে যতটা সম্ভব তথ্য দেওয়া এবং 4-মিলিয়ন সারি [Event]টেবিলটিতে একটি দক্ষ অ্যাক্সেস পদ্ধতি (সূচক) সরবরাহ করা ।


8

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

কার্যকর করার পরিকল্পনা আপনাকে জানায় যে এই সূচকটি কার্যকর হবে:

CREATE NONCLUSTERED INDEX ix_EventTypeID_PLCTimeStamp_WithIncludes
  ON [dbo].[Event] ([EventTypeID],[PLCTimeStamp])
  INCLUDE ([ID],[DeviceID],[Data1],[Data2],[IATA]);

যদিও আপনার ডেটা স্কিউয়ের উপর নির্ভর করে এটি অন্যান্য উপায়ে আরও ভাল হতে পারে যেমন:

CREATE NONCLUSTERED INDEX ix_PLCTimeStamp_EventTypeID_WithIncludes
  ON [dbo].[Event] ([PLCTimeStamp],[EventTypeID])
  INCLUDE ([ID],[DeviceID],[Data1],[Data2],[IATA]);

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

এত নিম্ন সারির গণনা সহ, আমি অবাক করতে হবে যে সম্ভবত বর্তমানে পারফরম্যান্সটি কতটা খারাপ হতে পারে? এই ক্যোয়ারিতে 3 টি সারি ফেরত এসেছে (তবে এটি কতগুলি সারি প্রত্যাখ্যান করেছে তার কোনও ইঙ্গিত নেই)। টেবিলের মধ্যে কত সারি?


4

আমি কেবল আবিষ্কার করেছি যে এসকিউএল সার্ভার ২০০৮ আর 2 আসলে কার্যকর করার পরিকল্পনাটি চালানোর সময় একটি সূচক পরামর্শ দেয়। এই প্রস্তাবিত সূচকটি ক্যোয়ারিকে প্রায় 90% দ্রুত চালায়।

সূচকের প্রস্তাবিতটি নিম্নলিখিত ছিল:

CREATE NONCLUSTERED INDEX [INDEX_spBagSearch] ON [dbo].[Event] 
(
    [EventTypeID] ASC,
    [PLCTimeStamp] ASC
)
INCLUDE ( [ID],
[DeviceID],
[Data1],
[Data2],
[IATA]) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.