এসকিউএল যেখানে আইডি রয়েছে (আইডি 1, আইডি 2,…, আইডিএন)


170

আইডির একটি বড় তালিকা পুনরুদ্ধার করতে আমার একটি ক্যোয়ারী লিখতে হবে।

আমরা অনেকগুলি ব্যাকেন্ডে (মাইএসকিউএল, ফায়ারবার্ড, এসকিউএল সার্ভার, ওরাকল, পোস্টগ্রিএসকিউএল ...) সমর্থন করি যাতে আমার একটি স্ট্যান্ডার্ড এসকিউএল লিখতে হবে।

আইডি সেটের আকারটি বড় হতে পারে, কোয়েরিটি প্রোগ্রামিকভাবে উত্পন্ন হবে। সুতরাং, সেরা পদ্ধতির কি?

1) IN ব্যবহার করে একটি কোয়েরি লেখা

SELECT * FROM TABLE WHERE ID IN (id1, id2, ..., idn)

আমার প্রশ্ন এখানে। এন খুব বড় হলে কী হবে? এছাড়াও, অভিনয় সম্পর্কে কি?

2) ওআর ব্যবহার করে একটি কোয়েরি লেখা

SELECT * FROM TABLE WHERE ID = id1 OR ID = id2 OR ... OR ID = idn

আমি মনে করি যে এই পদ্ধতির এন সীমা নেই, তবে এন খুব বড় হলে পারফরম্যান্সের কী হবে?

3) একটি প্রোগ্রামেটিক সমাধান রচনা:

  foreach (var id in myIdList)
  {
      var item = GetItemByQuery("SELECT * FROM TABLE WHERE ID = " + id);
      myObjectList.Add(item);
  }

নেটওয়ার্কে ডেটাবেস সার্ভারটি জিজ্ঞাসা করা হলে আমরা এই পদ্ধতির সাথে কিছু সমস্যা অনুভব করেছি। সাধারণত এমন একটি কোয়েরি করা ভাল যা প্রচুর ছোট প্রশ্ন তৈরির বিপরীতে সমস্ত ফলাফল পুনরুদ্ধার করে। হয়তো আমি ভুল.

এই সমস্যার সঠিক সমাধান কী হবে?


1
বিকল্প 1 টি এসকিউএল সার্ভারের প্রতিক্রিয়া সময়কে উল্লেখযোগ্যভাবে হ্রাস করে 7k আইডি নির্বাচন করে, যার মধ্যে কিছু উপস্থিত ছিল না। সাধারণত ক্যোয়ারীটি প্রায় 1300 মিমি নিয়েছিল, এটি ব্যবহার করে এটি হ্রাস করে 80 মিমি IN! আমি আপনার সমাধান 1 + 3 হিসাবে করেছি did ঠিক চূড়ান্ত ক্যোয়ারীটি ছিল একটি, দীর্ঘ জিজ্ঞাসার স্ট্রিংটি কার্যকর করার জন্য এসকিউএলকে প্রেরণ করা হয়েছিল।
পাইটর কুলা

উত্তর:


108

বিকল্প 1 একমাত্র ভাল সমাধান।

কেন?

  • বিকল্প 2 একই কাজ করে তবে আপনি কলামের নামটি বহুবার পুনরাবৃত্তি করেন; অতিরিক্তভাবে এসকিউএল ইঞ্জিন তাত্ক্ষণিকভাবে জানে না যে আপনি স্থির তালিকার মানগুলির মধ্যে একটি মান কিনা তা আপনি পরীক্ষা করতে চান। তবে, একটি ভাল এসকিউএল ইঞ্জিন এটির মতো সমান পারফরম্যান্স করতে এটি অনুকূল করতে পারে IN। এখনও পঠনযোগ্যতা ইস্যু আছে যদিও ...

  • বিকল্প 3 কেবল ভয়ঙ্কর পারফরম্যান্স-ভিত্তিক। এটি প্রতিটি লুপে একটি কোয়েরি প্রেরণ করে এবং ছোট প্রশ্নের সাথে ডাটাবেসটিকে হাতুড়ি করে। এটি "প্রদত্ত তালিকার মধ্যে একটির মান" এর জন্য কোনও অপ্টিমাইজেশন ব্যবহার করা থেকেও বাধা দেয়


2
আমি সম্মত তবে নোট করুন যে তালিকাটি অনেকগুলি আরডিএমএসের মধ্যে সীমাবদ্ধ এবং তাই আপনার আমাদের দরকার হতে পারে @ এড গুইন্সের সমাধানটি ব্যবহার করুন তবে এখানে অস্থায়ী টেবিলগুলি আরডিবিএমএসের মধ্যে পৃথক রয়েছে। (কার্যকরভাবে জটিল সমস্যার জন্য আপনি কেবল খাঁটি স্ট্যান্ডার্ড এসকিউএল ব্যবহার করতে পারবেন না)
মিমি মিমি মিমি

28

একটি বিকল্প পদ্ধতির আইডি মান ধারণ করতে অন্য টেবিল ব্যবহার করা হতে পারে। প্রত্যাবর্তিত সারিগুলিকে সীমাবদ্ধ করার জন্য এই অন্যান্য সারণীটি আপনার টেবিলে অভ্যন্তরীণভাবে যুক্ত হতে পারে। এটির প্রধান সুবিধা হ'ল আপনার ডায়নামিক এসকিউএল প্রয়োজন হবে না (সময়ের সেরা ক্ষেত্রে সমস্যাযুক্ত) এবং আপনার কাছে এই ধারা দীর্ঘকালীন থাকবে না।

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

আপডেট : যদিও আপনি একটি অস্থায়ী টেবিল ব্যবহার করতে পারেন, আমি বোঝাতে চাইনি যে আপনি অবশ্যই বা এমনকি করা উচিত should অস্থায়ী ডেটার জন্য ব্যবহৃত একটি স্থায়ী টেবিল হ'ল এখানে বর্ণিত beyond


1
তবে আপনার প্রয়োজনীয় আইডির তালিকাটি কীভাবে পাস করবেন? (দেখে আপনি কোনও ব্যাপ্তি বা এ জাতীয় কিছু নির্বাচন করতে পারবেন না)।
raam86

1
@ raam86: আইডিগুলির তালিকা selectঅন্য টেবিলে একটি বিবৃতি ব্যবহার করে প্রাপ্ত করা হতে পারে । আপনি যে অন্য টেবিলের inner joinবিপরীতে আছেন সেই তালিকাটি পাস হয়ে গেছে ।
বিডিফোর্বস

19

এড গিনিস যা প্রস্তাব করেছিলেন তা হ'ল একটি পারফরম্যান্স বুস্টার, আমার এই জাতীয় প্রশ্ন ছিল

select * from table where id in (id1,id2.........long list)

আমি কি করেছিলাম :

DECLARE @temp table(
            ID  int
            )
insert into @temp 
select * from dbo.fnSplitter('#idlist#')

তারপরে অভ্যন্তরীণ প্রধান টেবিলের সাথে টেম্পে যোগ দিল:

select * from table inner join temp on temp.id = table.id

এবং কর্মক্ষমতা মারাত্মক উন্নতি।


1
হাই, এমএনএসকিউএল থেকে একটি ফাংশন fnSplitter হয়? কারণ আমি এটি সন্ধান করতে সক্ষম হইনি।
WiiMaxx

এটি কোনও স্ট্যান্ডার্ড জিনিস নয়। তাদের অবশ্যই বোঝাতে হবে যে তারা এই উদ্দেশ্যে এই ফাংশনটি লিখেছিল বা উদাহরণস্বরূপ একটি অ্যাপ্লিকেশন রয়েছে যা এটি ইতিমধ্যে সরবরাহ করেছে।
আন্ডারস্কোর_২২

fnSplitter রিতু দ্বারা নির্মিত একটি ফাংশন, আপনি এটির অনুরূপ ইন্টারনেট / গুগলে খুঁজে পেতে পারেন
বাশার আবু শামা

9

প্রথম বিকল্পটি অবশ্যই সেরা বিকল্প।

SELECT * FROM TABLE WHERE ID IN (id1, id2, ..., idn)

তবে আইডির তালিকাটি খুব বিশাল যে বিবেচনা করে , মিলিয়ন বলুন, আপনার নীচের মতো নষ্ট আকারগুলি বিবেচনা করা উচিত:

  • আপনার আইডির তালিকাটি নির্দিষ্ট সংখ্যার অংশে ভাগ করুন, 100 বলুন
  • আপনার সার্ভারের মেমরির আকারের ভিত্তিতে খণ্ড আকারের সিদ্ধান্ত নেওয়া উচিত
  • ধরুন আপনার 10000 আইডি রয়েছে, আপনার 10000/100 = 100 টি অংশ হবে
  • নির্বাচনের জন্য ১০০ ডাটাবেস কল করার ফলে এক সময় এক অংশের প্রক্রিয়া করুন

আপনি খণ্ড খণ্ডে বিভক্ত করা উচিত কেন?

আপনি কখনই মেমরির ওভারফ্লো ব্যতিক্রম পাবেন না যা আপনার মতো দৃশ্যে খুব সাধারণ। আপনার কাছে আরও ভাল পারফরম্যান্সের ফলাফল হিসাবে সংখ্যক ডাটাবেস কল রয়েছে।

এটি আমার জন্য সর্বদা কবজির মতো কাজ করেছে। আশা করি এটি আমার সহযোগী বিকাশকারীদের জন্যও কার্যকর হবে :)


4

500 মিলিয়ন রেকর্ডের সাথে একটি অ্যাজুর এসকিউএল টেবিলের আইডি ইন () কমান্ডে * মাই টেবিল থেকে নির্বাচন করুন *> 7 মিনিটের অপেক্ষা সময়ের ফলে!

পরিবর্তে এটি করার ফলে অবিলম্বে ফলাফলগুলি ফিরে এসেছে:

select b.id, a.* from MyTable a
join (values (250000), (2500001), (2600000)) as b(id)
ON a.id = b.id

একটি যোগদান ব্যবহার করুন।


3

বেশিরভাগ ডাটাবেস সিস্টেমে IN (val1, val2, …)এবং একটি সিরিজ ORএকই পরিকল্পনায় অনুকূলিত হয়।

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

আপনি এই নিবন্ধগুলি পড়তে চাইতে পারেন:


3

নমুনা 3 এগুলির মধ্যে সবচেয়ে খারাপ পারফর্মার হতে পারে কারণ আপনি কোনও আপাত কারণ ছাড়াই অসংখ্যবার ডাটাবেসটিকে হিট করছেন।

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


2

আমি মনে করি আপনার স্ক্যালসার্ভারটি বোঝানো হয়েছে তবে ওরাকলটিতে আপনার কতটা নির্দিষ্ট উপাদান রয়েছে তা নির্দিষ্ট করতে পারবেন: 1000।


1
এমনকি এসকিউএল সার্ভার উপাদানগুলিতে k 40k পরে কাজ করা বন্ধ করে দেয়। এমএসডিএন অনুসারে: একটি আইএন ক্লজে অত্যন্ত সংখ্যক মান (বহু হাজার) অন্তর্ভুক্ত করা সম্পদ গ্রহণ করতে পারে এবং ত্রুটি return 86৩৩ বা ৮6363২ ফিরিয়ে আনতে পারে। এই সমস্যাটি সমাধান করার জন্য আইএন তালিকায় আইটেমগুলি একটি টেবিলের মধ্যে সংরক্ষণ করুন।
জাহাভ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.