tutorial - w3schools sql




SQL সার্ভারে INRER JOIN বনাম JOFT কার্য সম্পাদন (6)

অভ্যন্তরীণ যোগদান বাম যোগদানের চেয়ে দ্রুত কিনা চেক করার সময় আমি এসকিউএল সার্ভারে কিছু আকর্ষণীয় খুঁজে পেয়েছি।

যদি আপনি বাম যোগদানের টেবিলের আইটেমগুলি অন্তর্ভুক্ত না করেন তবে নির্বাচিত বিবৃতিতে, বাম যোগদান অভ্যন্তরীণ যোগদান সহ একই প্রশ্নের চেয়ে দ্রুততর হবে।

যদি আপনি নির্বাচিত বিবৃতিতে বাম যোগদানের সারণীটি অন্তর্ভুক্ত করেন তবে একই প্রশ্নের সাথে অভ্যন্তরীণ যোগদান বাম যোগদানের চেয়ে সমান বা দ্রুত ছিল।

আমি SQL কমান্ড তৈরি করেছি যা 9 টি টেবিলের জন্য INNER JOIN ব্যবহার করে, যাইহোক এই কমান্ডটি খুব দীর্ঘ সময় নেয় (পাঁচ মিনিটেরও বেশি)। তাই আমার লোকেরা আমাকে যোগ দিতে বামে যোগদান করতে ININER JOIN পরিবর্তন করতে পরামর্শ দেয় কারণ LEFT JOIN এর কার্যকারিতাটি আরও ভাল, যা আমি জানি তা সত্ত্বেও। আমি পরিবর্তন করার পরে, প্রশ্নের গতি উল্লেখযোগ্যভাবে উন্নত হয়।

আমি জানতে চাই কেন বামে যোগদান যোগদানকারীর চেয়ে দ্রুত?

আমার এসকিউএল কমান্ডটি নীচের মত দেখাচ্ছে: SELECT * FROM A INNER JOIN B ON ... INNER JOIN C ON ... INNER JOIN D এবং এভাবে

আপডেট: এই আমার স্কিমা সংক্ষিপ্ত।

FROM sidisaleshdrmly a -- NOT HAVE PK AND FK
    INNER JOIN sidisalesdetmly b -- THIS TABLE ALSO HAVE NO PK AND FK
        ON a.CompanyCd = b.CompanyCd 
           AND a.SPRNo = b.SPRNo 
           AND a.SuffixNo = b.SuffixNo 
           AND a.dnno = b.dnno
    INNER JOIN exFSlipDet h -- PK = CompanyCd, FSlipNo, FSlipSuffix, FSlipLine
        ON a.CompanyCd = h.CompanyCd
           AND a.sprno = h.AcctSPRNo
    INNER JOIN exFSlipHdr c -- PK = CompanyCd, FSlipNo, FSlipSuffix
        ON c.CompanyCd = h.CompanyCd
           AND c.FSlipNo = h.FSlipNo 
           AND c.FSlipSuffix = h.FSlipSuffix 
    INNER JOIN coMappingExpParty d -- NO PK AND FK
        ON c.CompanyCd = d.CompanyCd
           AND c.CountryCd = d.CountryCd 
    INNER JOIN coProduct e -- PK = CompanyCd, ProductSalesCd
        ON b.CompanyCd = e.CompanyCd
           AND b.ProductSalesCd = e.ProductSalesCd 
    LEFT JOIN coUOM i -- PK = UOMId
        ON h.UOMId = i.UOMId 
    INNER JOIN coProductOldInformation j -- PK = CompanyCd, BFStatus, SpecCd
        ON a.CompanyCd = j.CompanyCd
            AND b.BFStatus = j.BFStatus
            AND b.ProductSalesCd = j.ProductSalesCd
    INNER JOIN coProductGroup1 g1 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup1Cd
        ON e.ProductGroup1Cd  = g1.ProductGroup1Cd
    INNER JOIN coProductGroup2 g2 -- PK = CompanyCd, ProductCategoryCd, UsedDepartment, ProductGroup2Cd
        ON e.ProductGroup1Cd  = g2.ProductGroup1Cd

আপনি যে যোগদান করছেন সে সংখ্যা এবং আপনি যে কলামগুলিতে যোগদান করছেন তার সূচী আছে কিনা তা নিয়ে আপনার কর্মক্ষমতা সমস্যাগুলি বেশি হতে পারে।

সবচেয়ে খারাপ ক্ষেত্রে আপনি সহজেই 9 যোগ করতে প্রতিটি টেবিল স্ক্যান করতে পারে।


একটি গুরুত্বপূর্ণ দৃশ্যকল্প যে একটি অভ্যন্তরীণ যোগদান এখনো দ্রুত আলোচনা করা হয়েছে যে একটি বাইরের যোগদান হতে পারে।

বাইরের যোগদানের সময়, বাইরের টেবিলের PK থাকলে কলাম কলামটি বাইরের টেবিলের থেকে যদি কোনও কলাম নির্বাচন করা হয় তবে অপটিমাইজারটি এক্সিকিউশন প্ল্যান থেকে বাহ্যিক সংযুক্ত টেবিলটি মুছতে সবসময় মুক্ত থাকে। উদাহরণস্বরূপ SELECT A.* FROM A LEFT OUTER JOIN B ON A.KEY=B.KEY এবং BKEY এ B এর জন্য PK। ও ওরাকল উভয় (আমি বিশ্বাস করি যে আমি রিলিজ 10 ব্যবহার করছি) এবং SQL সার্ভার (আমি 2008 R2 ব্যবহার করেছি)। execution টেবিল থেকে প্রুন টেবিল বি।

অভ্যন্তরীণ যোগদানের জন্য এটি অপরিহার্যভাবে সত্য নয়: SELECT A.* FROM A INNER JOIN B ON A.KEY=B.KEY অস্তিত্বের উপর ভিত্তি করে নির্বাহ পরিকল্পনাতে B প্রয়োজন হতে পারে বা নাও হতে পারে।

যদি AKEY একটি বিন্যস্ত বিদেশী কী বি.কে.ই.কে উল্লেখ করে, তবে অপ্টিমাইজার প্ল্যান থেকে B কে বাদ দিতে পারে না কারণ এটি নিশ্চিত করতে হবে যে একটি সারি প্রতিটি সারির জন্য একটি সারি বিদ্যমান।

A.KEY যদি একটি আবশ্যক বাধ্যতামূলক বৈদেশিক কী, যা BKEY উল্লেখ করে তবে তারপরে অটোমাইজার প্ল্যান থেকে B কে মুক্ত করতে পারে কারণ সীমাবদ্ধতা সারির অস্তিত্বকে গ্যারান্টি দেয়। কিন্তু শুধুমাত্র অপ্টিমাইজার প্ল্যান থেকে টেবিল ড্রপ করতে পারেন, কারণ এটি হবে না মানে। এসকিউএল সার্ভার 2008 R2 পরিকল্পনা থেকে বি ড্রপ না। Oracle 10 পরিকল্পনা থেকে বি ড্র করতে দেয়। বাইরের যোগদানটি কীভাবে এই ক্ষেত্রে SQL সার্ভারে অভ্যন্তরীণ যোগদান করবে তা দেখতে সহজ।

এটি একটি তুচ্ছ উদাহরণ, এবং একটি স্ট্যান্ড একা প্রশ্নের জন্য ব্যবহারিক নয়। আপনি প্রয়োজন না হলে একটি টেবিলে যোগদান কেন?

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

বাইরের যোগদান ব্যবহার করে দেখুন সঠিক ফলাফল দেয় তা নিশ্চিত করার জন্য এটি গুরুত্বপূর্ণ। যেমন হান্নোট বলেছেন - আপনি অন্তর্নিহিত JOIN এর জন্য বাইরে যোগদান করতে পারবেন না এবং একই ফলাফল আশা করবেন। কিন্তু মতামত ব্যবহার করার সময় এটি কার্যকারিতার কারণে উপকারী হতে পারে।

একটি শেষ নোট - আমি উপরের আলোকে কর্মক্ষমতা সম্পর্কিত প্রভাব পরীক্ষা করে নিচ্ছি, কিন্তু তত্ত্বের মধ্যে মনে হচ্ছে আপনি একটি অভ্যন্তরীণ JOIN এর নিরাপদভাবে যোগদান করতে সক্ষম হবেন যদি আপনিও শর্তটি যোগ করেন <FOREIGN_KEY> নুল নয় যেখানে অধ্যায়।


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

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

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

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


যদি সবকিছু কাজ করে না তবে এটি করা উচিত নয়, তবে আমরা সবাই জানি যে কীভাবে এটি ক্রিয়া অপটিমাইজার, ক্যোয়ারী পরিকল্পনা ক্যাশিং এবং পরিসংখ্যানের ক্ষেত্রে বিশেষ করে যখন এটি করা উচিত সেভাবে কাজ করে না।

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

আমি কিছু ক্ষেত্রে অভিজ্ঞতা করেছি যেখানে একটি বাম যোগদান একটি অভ্যন্তরীণ যোগদান চেয়ে দ্রুত হয়েছে।

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

যদি অপটিমাইজার বাম যোগদানটি অপ্টিমাইজ করতে পছন্দ করে তবে এটি লেখা হয় যে এটি অভ্যন্তরীণ যোগানের চেয়ে ভাল সঞ্চালন করবে।

কিন্তু, অপটিমাইজার বাম আধা যোগদান হিসাবে উপ-অপ্টিমাইলে বাম যোগদানটিও অপ্টিমাইজ করতে পারে। আপনি চান যে এটি চয়ন করতে আপনি বল অর্ডার ইঙ্গিত ব্যবহার করতে পারেন।


শেষে উভয় প্রশ্নের (অভ্যন্তরীণ এবং বাম যোগদান সহ) OPTION (FORCE ORDER) এবং ফলাফল পোস্ট করুন। OPTION (FORCE ORDER) একটি প্রশ্নসূচক ইঙ্গিত যা ক্যোয়ারিতে প্রদত্ত যোগসূত্রের সাথে অপ্টিমাইজারকে কার্যকরকরণ পরিকল্পনাটি নির্মাণ করতে বাধ্য করে।

INNER JOIN LEFT JOIN হিসাবে দ্রুত সঞ্চালন শুরু করলে, এটি কারণ:

  • INNER JOIN এর দ্বারা সম্পূর্ণরূপে তৈরি একটি ক্যোয়ারীতে, যোগদান আদেশ কোন ব্যাপার না। এটি ক্যোয়ারী অপটিমাইজারের জন্য স্বাধীনতা দেয় যাতে যোগদানের উপযুক্ত হিসাবে এটি অর্ডার করতে পারে, তাই সমস্যাটি অপটিমাইজারের উপর নির্ভর করে।
  • LEFT JOIN সঙ্গে, যে ক্ষেত্রে না কারণ যোগদান ক্রম পরিবর্তন ক্যোয়ারী ফলাফল পরিবর্তন হবে। এর অর্থ হল ইঞ্জিনটি অবশ্যই আপনার প্রশ্নের জবাবে প্রদত্ত যোগসূত্র অনুসরণ করতে হবে, যা অপ্টিমাইজেশান একের চেয়ে ভাল হতে পারে।

আপনার প্রশ্নের উত্তরটি যদি জানতে না পারে তবে আমি একবার এমন একটি প্রকল্পে ছিলাম যা জটিল জটিল প্রশ্নগুলি গণনা করে যা সম্পূর্ণরূপে অপটিমাইজারকে আপোস করে। আমাদের ক্ষেত্রে এমন একটি কেস ছিল যেখানে কোনও FORCE ORDER একটি ক্যোয়ারীর নির্বাহের সময়কে 5 মিনিট থেকে 10 সেকেন্ডের মধ্যে কমাবে।





performance