সেগুলি লিখিতভাবে ক্রমগুলি কোথায় প্রয়োগ করা হয়েছে?


36

আমি একটি কোয়েরিটি অপ্টিমাইজ করার চেষ্টা করছি যা একটি বড় টেবিল (৩ millions মিলিয়ন সারি) দেখে এবং একটি কোয়েরিতে ক্রিয়াকলাপগুলি কী আদেশে কার্যকর করা হয় সে সম্পর্কে একটি প্রশ্ন রয়েছে।

select 1 
from workdays day
where day.date_day >= '2014-10-01' 
    and day.date_day <= '2015-09-30' 
    and day.offer_id in (
        select offer.offer_day 
        from offer  
        inner join province on offer.id_province = province.id_province  
        inner join center cr on cr.id_cr = province.id_cr 
        where upper(offer.code_status) <> 'A' 
            and province.id_region in ('10' ,'15' ,'21' ,'26' ,'31' , ...,'557') 
            and province.id_cr in ('9' ,'14' ,'20' ,'25' ,'30' ,'35' ,'37')
    )

করছেন WHEREতারিখ ব্যাপ্তির জন্য ক্লজ subquery আগে মৃত্যুদন্ড কার্যকর? দ্রুত সম্পাদন করার জন্য, অন্যান্য ধারাগুলির বড় লুপগুলি এড়াতে প্রথমে সবচেয়ে সীমাবদ্ধ ধারাগুলি রাখার কি ভাল উপায়?

এখন অনুসন্ধানগুলি কার্যকর করতে এত বেশি সময় নেয়।

উত্তর:


68

@ আলসির উত্তরটি বিস্তারিতভাবে জানাতে:

পোস্টগ্রিএসকিউএল আপনার কোন অর্ডারে জিনিস লিখবে তা যত্ন করে না

  • পোস্টগ্রেএসকিউএল কোনও ধারাতে প্রবেশের ক্রমটির বিষয়ে মোটেও পাত্তা দেয় না WHEREএবং কেবলমাত্র ব্যয় এবং নির্বাচনী অনুমানের উপর ভিত্তি করে সূচী এবং সম্পাদন আদেশ চয়ন করে।

  • যে ক্রমে যোগদান করা হয় সেটিকে কনফিগার করা অবধিও উপেক্ষা করা হবে join_collapse_limit; যদি এর চেয়ে আরও বেশি কিছু যোগ দেয় তবে এটি তাদের লিখিত ক্রমে কার্যকর করবে।

  • বাহ্যিক ক্যোয়ারী প্রকৃতপক্ষে তথ্যের প্রয়োজন হওয়ার আগে সাবকিউরিটি কার্যকর করা হয়, তত দ্রুত যা নির্ভর করে সেগুলিতে থাকা কোয়েরির আগে বা পরে সম্পাদন করা যেতে পারে। প্রায়শই বাস্তবে সাবকোয়ারি মাঝখানে ফাঁসিয়ে দেওয়া হয় বা বাইরের প্রশ্নের সাথে ইন্টারলিভড হয়।

  • পোস্টগ্র্রেএসকিউএল আসলে ক্যোয়ারির কিছু অংশ কার্যকর করবে এমন কোনও গ্যারান্টি নেই। এগুলি পুরোপুরি অপ্টিমাইজ করা যায়। আপনি যদি পার্শ্ব প্রতিক্রিয়াযুক্ত ফাংশনগুলি কল করেন এটি গুরুত্বপূর্ণ।

PostgreSQL আপনার ক্যোয়ারী রূপান্তরিত করবে

ফলাফল পরিবর্তন না করার সময় তাদের দ্রুত চালানোর জন্য পোস্টগ্র্রেএসকিউএলগুলি একই একই প্রভাবগুলি ধরে রাখার সাথে সাথে প্রশ্নেরগুলি ভারীভাবে রূপান্তরিত করবে।

  • সাবকিউরির বাইরের শর্তাদি সাবকোয়ারিতে নিচে নামতে পারে যাতে তারা বাহ্যিক ক্যোয়ারিতে যেখানে সেগুলি লিখেছিল তা নয় সাব-কোয়েরির অংশ হিসাবে কার্যকর করে

  • সাবকিউরিতে শর্তাদি বাইরের ক্যোয়ারিতে টানা যেতে পারে তাই বাহ্যিক ক্যোয়ারির অংশ হিসাবে তাদের সম্পাদন সম্পন্ন হয়, যেখানে আপনি সেগুলি সাব-কোয়েরিতে লিখেছেন তা নয়

  • সাবকোয়ারিটি প্রায়শই এবং বাইরের টেবিলের জোড়ে চ্যাপ্টা হয়ে যায়। মত EXISTSএবং NOT EXISTSকোয়েরিগুলির ক্ষেত্রেও এটি একই ।

  • দর্শনগুলি ব্যবহার করে এমন ক্যোয়ারিতে ভিউগুলি সমতল হয়ে যায়

  • এসকিউএল ফাংশন প্রায়শই কলিং কোয়েরিতে অন্তর্ভুক্ত হয়

  • ... এবং ক্যোয়ারিতে আরও অনেকগুলি রূপান্তর রয়েছে, যেমন ধ্রুবক প্রকাশের প্রাক-মূল্যায়ন, কিছু উপকণার ডি-রিলেশন, এবং অন্যান্য পরিকল্পনাকারী / অপ্টিমাইজার কৌশলগুলি।

সাধারণভাবে পোস্টগ্রিসকিউএল আপনার ক্যোয়ারিকে ব্যাপকভাবে রূপান্তর করতে এবং পুনরায় লিখন করতে পারে, যেখানে এই প্রতিটি প্রশ্নের প্রত্যেকটিতে:

select my_table.*
from my_table
left join other_table on (my_table.id = other_table.my_table_id)
where other_table.id is null;

select *
from my_table
where not exists (
  select 1
  from other_table
  where other_table.my_table_id = my_table.id
);

select *
from my_table
where my_table.id not in (
  select my_table_id
  from other_table
  where my_table_id is not null
);

সাধারণত সবাই একই ক্যোয়ারী প্ল্যান তৈরি করে। (ধরে নিচ্ছি যে যাইহোক আমি উপরেরগুলিতে কোনও বোবা ভুল করি নি)।

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

সীমাবদ্ধতা

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

  • পরিকল্পনাকারীর দ্বারা রাখা পরিসংখ্যানগুলির উপর নির্ভর করে ANALYZE(সাধারণত অটোভ্যাকুমের মাধ্যমে)। এগুলি যদি পুরানো হয় তবে পরিকল্পনার পছন্দটি খারাপ হতে পারে।

  • পরিসংখ্যানগুলি কেবলমাত্র একটি নমুনা, তাই নমুনা প্রভাবের কারণে এগুলি বিভ্রান্তিকর হতে পারে, বিশেষত যদি খুব ছোট কোনও নমুনা নেওয়া হয়। খারাপ পরিকল্পনা পছন্দ ফলাফল হতে পারে।

  • পরিসংখ্যানগুলি টেবিল সম্পর্কে কিছু ধরণের ডেটা যেমন কলামগুলির মধ্যে পারস্পরিক সম্পর্ককে ট্র্যাক করে না। এটি পরিকল্পনাকারীকে খারাপ সিদ্ধান্ত নিতে নেতৃত্ব দিতে পারে যখন এটি ধরে নেওয়া হয় যে জিনিসগুলি যখন না থাকে তখন তারা স্বাধীন থাকে।

  • পরিকল্পনাকারী ব্যয় পরামিতিগুলির উপর নির্ভর করে random_page_costএটি নির্দিষ্ট করা সিস্টেমে বিভিন্ন অপারেশনের আপেক্ষিক গতিটি বলতে চাইলে এটি ইনস্টল করা আছে। এগুলি কেবল গাইড। যদি তারা খারাপভাবে ভুল হয় তবে তারা খারাপ পরিকল্পনা পছন্দ করতে পারে।

  • একটি LIMITবা সহ যে কোনও subquery সমতল বা পলআপ / পুশডাউন সাপেক্ষে OFFSETহতে পারে না। এর অর্থ এই নয় যে এটি বাহ্যিক ক্যোয়ারীর সমস্ত অংশের আগেই কার্যকর করা হবে, এমনকি এটি এমনকি কার্যকর করা হবে

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

  • বিদেশী টেবিল, security_barrierদর্শন এবং কিছু অন্যান্য বিশেষ প্রকারের সম্পর্কের প্রশ্নগুলিতে পোস্টগ্রিএসকিউএল এর সীমাবদ্ধ ক্ষমতা রয়েছে

  • পোস্টগ্রেএসকিউএল সাধারণ প্যাকেজ এসকিউএল ব্যতীত অন্য কোনও লিখিত ফাংশনকে ইনলাইন করবে না এবং এর এবং বাইরের ক্যোয়ারির মধ্যে পুলআপ / পুশডাউন করবে না।

  • পরিকল্পনাকারী / অপ্টিমাইজারটি এক্সপ্রেশন সূচকগুলি নির্বাচন করার বিষয়ে, এবং সূচক এবং প্রকাশের মধ্যে তুচ্ছ তথ্য প্রকারের পার্থক্য সম্পর্কে মূ .়।

আরও অনেক বেশি।

আপনার প্রশ্ন

আপনার প্রশ্নের ক্ষেত্রে:

select 1 
from workdays day
where day.date_day >= '2014-10-01' 
    and day.date_day <= '2015-09-30' 
    and day.offer_id in (
        select offer.offer_day 
        from offer  
        inner join province on offer.id_province = province.id_province  
        inner join center cr on cr.id_cr = province.id_cr 
        where upper(offer.code_status) <> 'A' 
            and province.id_region in ('10' ,'15' ,'21' ,'26' ,'31' , ...,'557') 
            and province.id_cr in ('9' ,'14' ,'20' ,'25' ,'30' ,'35' ,'37')
    )

কোনও অতিরিক্ত সেট যোগ দেওয়ার সাথে এটি একটি সহজ ক্যোয়ারিতে ফ্ল্যাট করা থেকে কোনও কিছুই থামায় না এবং এটি সম্ভবত সম্ভবত হবে।

এটি সম্ভবত (অনাস্থিত, স্পষ্টতই) এর মতো কিছু তৈরি করবে:

select 1 
from workdays day
inner join offer on day.offer_id = offer.offer_day
inner join province on offer.id_province = province.id_province  
inner join center cr on cr.id_cr = province.id_cr 
where upper(offer.code_status) <> 'A' 
   and province.id_region in ('10' ,'15' ,'21' ,'26' ,'31' , ...,'557') 
   and province.id_cr in ('9' ,'14' ,'20' ,'25' ,'30' ,'35' ,'37')
   and day.date_day >= '2014-10-01' 
   and day.date_day <= '2015-09-30';

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

অপ্টিমাইজার কী করেছে তা দেখুন

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

এই ক্যোয়ারী পরিকল্পনা বা অভ্যন্তরীণ পরিকল্পনার গাছটি এসকিউএলে ফিরে যাওয়ার "বিযুক্ত" করার কোনও উপায় নেই।

http://explain.depesz.com/ এর একটি শালীন ক্যোয়ারি প্ল্যান সহায়ক রয়েছে। আপনি যদি পরিকল্পনাগুলি ইত্যাদি জিজ্ঞাসা করতে সম্পূর্ণ নতুন হন (এই ক্ষেত্রে আমি আপনাকে অবাক করে দিয়েছি যে আপনি এই পোস্টের মাধ্যমে এটিকে এতদূর তৈরি করেছেন) তবে পিজএডমিনের একটি গ্রাফিকাল ক্যোয়ারী প্ল্যান ভিউয়ার রয়েছে যা অনেক কম তথ্য সরবরাহ করে তবে সহজ ler

সম্পর্কিত পড়া:

পুশডাউন / পুলআপ এবং সমতলকরণ ক্ষমতা প্রতিটি রিলিজের উন্নতি অবিরত করে । পোস্টগ্রাইএসকিউএল সাধারণত পুল-আপ / পুশ-ডাউন / চাটুকারকৃত সিদ্ধান্ত সম্পর্কে সঠিক, তবে সর্বদা নয়, তাই মাঝে মাঝে আপনাকে সিটিই বা OFFSET 0হ্যাক ব্যবহার করতে হয় (আব) । যদি আপনি এরকম কেস পান তবে একটি ক্যোয়ারী পরিকল্পনাকারী বাগটি রিপোর্ট করুন।


আপনি যদি সত্যই হন তবে সত্যই আগ্রহী আপনি debug_print_plansকাঁচা ক্যোয়ারী পরিকল্পনাটি দেখতে বিকল্পটিও ব্যবহার করতে পারেন তবে আমি প্রতিশ্রুতি দিচ্ছি যে আপনি এটি পড়তে চান না। সত্যিই।


বাহ ... বেশ সম্পূর্ণ উত্তর :-) পোস্টগ্র্রেসক্লেলের সাথে ধীরে ধীরে আমার পরিকল্পনা ছিল (তেমনি ওরাকল এর মতো অন্যান্য সুপরিচিত ডিবি ইঞ্জিনগুলির সাথেও) কলামগুলির মধ্যে পারস্পরিক সম্পর্ক রয়েছে বা একাধিক পারস্পরিক সম্পর্কযুক্ত যোগ রয়েছে of এটি প্রায়শই নেস্টেড লুপগুলি শেষ করে ভাববে যে পরিকল্পনার এই পর্যায়ে কেবল কয়েকটি সারি রয়েছে, যখন বাস্তবে অনেক হাজার রয়েছে। এই ধরণের প্রশ্নগুলির অনুকূলকরণের একটি উপায় হ'ল 'সক্ষম করুন_নেস্টলুপ = অফ; ক্যোয়ারির সময়কালের জন্য।
alci

আমি এমন একটি পরিস্থিতিতে ছুঁড়েছি যেখানে v9.5.5 চেক করার আগে TO_DATE প্রয়োগ করার চেষ্টা করছিল, সাধারণ 7 যেখানে ক্লজ কোয়েরি applied অর্ডার ম্যাটার।
ব্যবহারকারী 1133275

@ user1133275 সেক্ষেত্রে এটি কেবল আপনার পক্ষে সুযোগেই কাজ করেছে, কারণ গণনার ব্যয়ের হিসাবের হিসাব একই ছিল। পোস্টগ্রিএসকিউএল এখনও to_dateপরবর্তী সংস্করণে বা কিছু আশাবাদী পরিসংখ্যান পরিবর্তনের কারণে চেকের আগে চালানোর সিদ্ধান্ত নিতে পারে । করতে নির্ভরযোগ্যভাবে একটি ফাংশন যে শুধুমাত্র চেক পরে চালানো উচিত সামনে একটি চেক চালানোর জন্য, একটি ব্যবহার CASEবিবৃতি।
ক্রেগ রিঞ্জার

আমি কখনও কখনও দেখেছি দুর্দান্ত উত্তরগুলির মধ্যে একটি ! থাম্বস আপ, মানুষ!
62mkv

আমি এমন পরিস্থিতিগুলির অভিজ্ঞতা পেয়েছি যেখানে সাধারণ ক্যোয়ারী যুক্ত order byকরার সাথে ক্যোয়ারি কার্যকরকরণের সংখ্যাটি যদি না থাকে তার চেয়ে অনেক দ্রুত করে তোলে order by। আমি আমার ক্যোয়ারীগুলিকে এইভাবে যোগদানের সাথে যুক্ত করার কারণগুলির মধ্যে এটির একটি যাতে আমি মৃত্যুদণ্ড কার্যকর করতে চেয়েছিলাম - এটির দুর্দান্ত অপটিমাইজারটি পাওয়া খুব ভাল তবে আমি মনে করি যে আপনার পরিণামের সম্পূর্ণ পরিণতিতে বিশ্বাস করা এবং কীভাবে চিন্তা না করে প্রশ্নগুলি লেখাই বুদ্ধিমানের কাজ নয় এটি may beকার্যকর করা হয়েছে ... দুর্দান্ত উত্তর !!
Greg0ry

17

এসকিউএল একটি ঘোষণামূলক ভাষা: আপনি কী চান তা বলুন, কীভাবে এটি করবেন না। আরডিবিএমএস কোয়েরিটি কার্যকর করার পদ্ধতিটি বেছে নেবে, তাকে এক্সিকিউশন প্ল্যান বলে।

একসময় (৫-১০ বছর আগে), যেভাবে কোনও ক্যোয়ারী লেখা হয়েছিল তা কার্যকরভাবে প্রয়োগের পরিকল্পনার উপর সরাসরি প্রভাব ফেলেছিল, তবে আজকাল বেশিরভাগ এসকিউএল ডাটাবেস ইঞ্জিন পরিকল্পনার জন্য একটি কাস্ট বেসড অপ্টিমাইজার ব্যবহার করে। এটি হ'ল এটি ডাটাবেস অবজেক্টগুলিতে তার পরিসংখ্যানের ভিত্তিতে ক্যোয়ারি চালানোর জন্য বিভিন্ন কৌশল মূল্যায়ন করবে এবং সেরাটি বেছে নেবে।

বেশিরভাগ সময়, এটি সত্যই সেরা, তবে কখনও কখনও ডিবি ইঞ্জিন খারাপ পছন্দ করে, ফলে খুব ধীর অনুসন্ধান হয়।


এটি লক্ষ করা উচিত যে কিছু আরডিবিএমএস-এ কোয়েরি ক্রমটি এখনও তাত্পর্যপূর্ণ তবে আরও উন্নতদের জন্য আপনি যা বলেছেন তা বাস্তবে তত্ত্বের পাশাপাশি সত্য। যখন ক্যোয়ারি পরিকল্পনাকারী কার্যকর করার আদেশের খারাপ পছন্দগুলি বাছাই করে থাকে তখন সাধারণত আরও কার্যকর দিকটিতে ধাক্কা দেওয়ার জন্য ক্যোয়ারী ইঙ্গিতগুলি পাওয়া যায় (যেমন WITH(INDEX(<index>))এমএসএসকিউএলে কোনও নির্দিষ্ট যোগদানের জন্য সূচী পছন্দকে বাধ্য করার জন্য)।
ডেভিড স্পিলিট

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