একটি বিদেশী কীতে সুস্পষ্ট একক KEY মান সহ মার্জ যোগ (আইএনডেক্স স্ক্যান) কে জয় করুন


9

মার্জ যোগ দেওয়ার সময় সূচী স্ক্যানের কারণে সমস্যাটি হ'ল সমস্যাগুলি হ'ল //১১ এক্ষেত্রে একটি লেনদেন এফকে প্যারেন্ট টেবিলে পুরো সূচকে এস লক আনার চেষ্টা করে তবে এর আগে অন্য একটি লেনদেন সূচকের মূল মানকে এক্স লক রাখে।

আমাকে একটি ছোট উদাহরণ দিয়ে শুরু করা যাক (70-461 ক্রোসর ব্যবহৃত TSQL2012 DB থেকে):

CREATE TABLE [Sales].[Orders](
[orderid] [int] IDENTITY(1,1) NOT NULL,
[custid] [int] NULL,
[empid] [int] NOT NULL,
[shipperid] [int] NOT NULL,
... )

কলামগুলি সেই অনুসারে [custid], [empid], [shipperid]কোরলেটেড পরামিতি are [Sales].[Customers], [HR].[Employees], [Sales].[Shippers]প্রতিটি ক্ষেত্রে একটি পারেন্ট টেবিলের মধ্যে উল্লেখ করা কলামে আমাদের একটি ক্লাস্টার ইনডেক্স রয়েছে।

ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Customers] FOREIGN KEY([custid]) REFERENCES [Sales].[Customers] ([custid])
ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Employees] FOREIGN KEY([empid]) REFERENCES [HR].[Employees] ([empid])
ALTER TABLE [Sales].[Orders]  WITH CHECK ADD  CONSTRAINT [FK_Orders_Shippers] FOREIGN KEY([shipperid])REFERENCES [Sales].[Shippers] ([shipperid])

আমি INSERT [Sales].[Orders] SELECT ... FROMঅন্য একটি টেবিলে চেষ্টা করছি [Sales].[OrdersCache]যার নাম [Sales].[Orders]বিদেশী কী বাদে একই কাঠামোযুক্ত । সারণীর উল্লেখ করা আরেকটি বিষয় গুরুত্বপূর্ণ হতে পারে [Sales].[OrdersCache]হ'ল একটি ক্লাস্টারড ইনডেক্স।

CREATE CLUSTERED INDEX idx_c_OrdersCache ON Sales.OrdersCache ( custid, empid )

প্রত্যাশিত যখন I`m একটি নিম্ন পরিমাণের ডেটা sertোকানোর চেষ্টা করছে LOOP JOIN বিদেশী কীগুলিতে সূচক তৈরির সূচনা করে works

উচ্চ মাত্রার ডেটা সহ মার্জ জিন কোয়েরি ফরগেন কী বজায় রাখার সবচেয়ে দক্ষ উপায় হিসাবে ক্যোয়ারী অপ্টিমাইজার দ্বারা ব্যবহৃত হয়।

এবং বিদেশী কী বা সুস্পষ্ট যোগদানের ক্ষেত্রে INNER LOOP JOIN এর সাথে আমাদের ক্ষেত্রে অপশন (লুপ জয়েন) ব্যবহার করে এগুলি করার কিছুই নেই।

নীচে আইওএম আমার পরিবেশে চালানোর চেষ্টা করছি:

INSERT Sales.Orders (
        custid, empid, shipperid, ... )
SELECT  custid, empid, 2, ...
FROM Sales.OrdersCache

পরিকল্পনার দিকে তাকিয়ে আমরা দেখতে পাচ্ছি যে মার্জিন जॉিনের সাথে 3 টি ফোরিং কী বৈধ হয়েছে। এটি আমার পক্ষে উপযুক্ত উপায় নয় কারণ এটি সম্পূর্ণ সূচক লকিংয়ের সাথে ইন্ডেক্স স্ক্যান ব্যবহার করে। বিদেশী কী বৈধতা যাবার সময় মার্জ যোগ দিন

অপশন (লুপ জয়েন) ব্যবহার করা উপযুক্ত নয় কারণ এটি মার্জ যোগিনের চেয়ে প্রায় 15% বেশি খরচ করে (আমার মনে হয় ডেটা ভলিউমের বৃদ্ধির সাথে সাথে রিগ্রেশনটি আরও বেশি হবে)।

নির্বাচিত বিবৃতিতে আপনি shipperidপুরো sertedোকানো সেটটির জন্য গুণকের জন্য একক মান দেখতে পারেন । আমার মতে অন্তত অপরিবর্তনীয় বৈশিষ্ট্যের জন্য সন্নিবেশিত সেটটির জন্য বৈধতা পর্বটি দ্রুত করার একটি উপায় অবশ্যই থাকতে হবে। কিছুটা এইরকম:

  • লুপ জয়েন করুন, মার্জ যোগ দিন, যোগ দিন যদি আমাদের যোগদানের বৈধতার জন্য অপরিবর্তিত সাবসেট থাকে
  • বৈধতাযুক্ত কলামটির যদি কেবল একটি একক সুস্পষ্ট মান থাকে তবে আমরা বৈধকরণটি কেবল একবারই করি (INDEX অনুসন্ধান)।

কোড স্ট্রাকচার, অতিরিক্ত ডিডিএল অবজেক্ট ইত্যাদি ব্যবহার করে উপরের পরিস্থিতি অতিক্রম করার জন্য কি সাধারণ প্যাটার্ন রয়েছে?

20/07 যোগ করা হয়েছে। সমাধান। কোয়েরি অপ্টিমাইজার ইতিমধ্যে মার্জ যোগ দিয়ে একটি 'একক কী - বিদেশী কী' বৈধকরণ অপ্টিমাইজেশন তৈরি করে। এবং কেবল বিক্রয়.শ্পিপারস টেবিলের জন্য তৈরি করে, একই সময়ে ক্যোয়ারিতে অন্য কোনও যোগ দেওয়ার জন্য LOOP JOIN রেখে। যেহেতু প্যারেন্ট টেবিলে আমার কয়েকটি সারি রয়েছে ক্যোরি অপটিমাইজার সজ্জা-মার্জ যুক্ত অ্যালগরিদমে যোগদান করে এবং অভ্যন্তরীণ টেবিলের প্রতিটি সারিটি পিতামাতার টেবিলের সাথে একবারে তুলনা করে। সুতরাং আমার প্রশ্নের উত্তরটি যদি কোনও একক কী কার্যকরকরণের সময় কোনও সেটগুলিতে কার্যকরভাবে প্রক্রিয়াজাত করার জন্য কোনও বিশেষ পদ্ধতি থাকে। এটি এত নিখুঁত সিদ্ধান্ত নয় তবে এসকিউএল সার্ভার যেভাবে মামলাটিকে অনুকূল করে।

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

উত্তর:


8

অপশন (লুপ জয়েন) ব্যবহার করা উপযুক্ত নয় কারণ এটি মার্জ যোগ দিয়ে প্রায় 15% বেশি খরচ করে

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

আমার অভিজ্ঞতায়, লুপগুলি থেকে অপ্টিমাইজারটি খুব তাড়াতাড়ি বিদেশী কী বৈধতার জন্য মেশাতে যোগ দিতে যোগ দেয়। বৃহত্তম ক্রিয়াকলাপ ব্যতীত, আমি লুপগুলি পছন্দনীয় হতে দেখলাম। এবং "বৃহত্তর" দ্বারা আমি বোঝাচ্ছি কমপক্ষে কয়েক মিলিয়ন সারি, অবশ্যই হাজার নয় তাই আপনি আপনার প্রশ্নের মন্তব্যে নির্দেশ করেছেন।

আমার মতে অন্তত অপরিবর্তনীয় বৈশিষ্ট্যের জন্য সন্নিবেশিত সেটটির জন্য বৈধতা পর্বটি দ্রুত করার একটি উপায় অবশ্যই থাকতে হবে।

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

কোড স্ট্রাকচার, অতিরিক্ত ডিডিএল অবজেক্ট ইত্যাদি ব্যবহার করে উপরের পরিস্থিতি অতিক্রম করার জন্য কি সাধারণ প্যাটার্ন রয়েছে?

এমন নয় যে আমি জানিনা. বৈদেশিক কী বৈধকরণ সংযুক্তির সাথে অচলাবস্থার ঝুঁকিটি সুপরিচিত , সবচেয়ে বহুল ব্যবহৃত ব্যবহৃত কাজটি OPTION (LOOP JOIN)ইঙ্গিত হিসাবে। বিদেশী কী বৈধকরণের সময় ভাগ করা লকগুলি এড়ানো কোনও উপায় নেই, কারণ এগুলি যথাযথতার জন্য প্রয়োজনীয় , এমনকি সারি-সংস্করণ বিচ্ছিন্নতা স্তরেরও অধীনে।

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

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