এসকিউএল সার্ভার ত্রুটি 8632 কারবারের শর্তে 100,000 এর বেশি এন্ট্রিগুলির কারণে


16

আমার সমস্যা (বা কমপক্ষে ত্রুটির বার্তা) খুব ক্যোয়ারী প্রসেসরের সাথে অভ্যন্তরীণ সংস্থানসমূহের বাইরে চলে এসেছে - অত্যন্ত দীর্ঘ এসকিএল কোয়েরি

আমার গ্রাহক একটি এসকিউএল নির্বাচন-ক্যোয়ারী নিয়ে কাজ করছেন, যেখানে হ'ল শুল্ক সহ 100,000 এন্ট্রি রয়েছে।

ক্যোয়ারী ত্রুটি 8632 এবং ত্রুটি বার্তায় ব্যর্থ হচ্ছে

অভ্যন্তরীণ ত্রুটি: একটি অভিব্যক্তি পরিষেবা সীমাতে পৌঁছেছে। আপনার প্রশ্নে সম্ভাব্য জটিল এক্সপ্রেশনটি দেখুন এবং সেগুলি সরল করার চেষ্টা করুন))

আমি এটি খুব অদ্ভুত বলে মনে করি যে এই ত্রুটি বার্তাটি ঠিক 100,000 এন্ট্রিতে নিক্ষেপ করা হয়েছে, তাই আমি ভাবছি এটি কনফিগারযোগ্য মান কিনা। এটি কি এই ক্ষেত্রে এবং হ্যাঁ ক্ষেত্রে, আমি কীভাবে এই মানটিকে আরও উচ্চতর করে তুলতে পারি?

উপর দুটিই MSDN সেখানে প্রস্তাব ক্যোয়ারী পুনরায় পুনর্লিখন, কিন্তু আমি এই সমস্যা এড়ানোর করতে চাই।

ইতিমধ্যে আমি জানতে পেরেছি যে আমি যে এন্ট্রিগুলির কথা বলছি তার তালিকায় প্রাকৃতিক সংখ্যা রয়েছে, তাদের বেশিরভাগটি অনুক্রমিক বলে মনে হচ্ছে (এরকম কিছু (1,2,3,6,7,8,9,10,12, 13,15,16,17,18,19,20)।

এটি এসকিউএলকে যেখানে ক্লজ-এর মতো কিছু করে তোলে:

where entry in (1,2,3,6,7,8,9,10,12,13,15,16,17,18,19,20)

আমি এটিকে রূপান্তর করতে পারি:

where (entry between 1 and 3) OR
      (entry between 6 and 10) OR
      (entry between 12 and 13) OR
      (entry between 15 and 20)

এটি কি সংক্ষিপ্ত করা যেতে পারে:

where entry in (1,...,3,6,...,10,12,13,15,...,20)

... নাকি এরকম কিছু? (আমি জানি এটি একটি দীর্ঘ শট, তবে এটি সফ্টওয়্যার আপডেটগুলি আরও সহজ এবং আরও পঠনযোগ্য করে তুলবে)

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


7
আপনার সম্পাদনার জবাবে: না, WHERE INএই ধরণের রেঞ্জ সিনট্যাক্স সমর্থন করে না। এছাড়াও, এটি ও হওয়া উচিত WHERE () OR () OR ()নয়। তবে ব্রেন্টের পরামর্শটি ব্যবহার করার জন্য আপনাকে আসলে পুরো ক্যোয়ারীটি পরিবর্তন করতে হবে না, আপনি কেবল এটি করতে পারেন WHERE IN (SELECT myID FROM #biglist)। এবং #biglistহয় একটি বাস্তব (স্থায়ী) টেবিল হতে পারে, বা আপনি ঝাঁকুনিতে তৈরি একটি টেম্প টেবিল।
ব্র্যাডিসি 8:58

দয়া করে পুরো ক্যোয়ারী এবং আপনি বাহ্যিকভাবে যা গণনা করছেন তা পোস্ট করুন, এটি সম্ভবত সত্যিই এমন কিছু যা আপনি সম্পূর্ণরূপে এসকিউএলে করতে পারেন। আপনি যদি গোপনীয়তা বা যা কিছু সম্পর্কে উদ্বিগ্ন থাকেন তবে ক্ষেত্রের নামগুলি পুনরায় নামকরণ করুন।
মাইক 14

উত্তর:


67

১০০,০০০ এর বেশি মান সন্ধানের জন্য এগুলি পরিবর্তে একটি টেম্প টেবিলের মধ্যে রাখুন, আপনি যে মানটি অনুসন্ধান করছেন তার প্রতি এক সারি। তারপরে, ফিল্টারিংয়ের জন্য সেই টেম্প টেবিলটিতে আপনার ক্যোয়ারিতে যোগদান করুন।

১০০,০০০ এরও বেশি মান সহকারে এমন কিছু পরামিতি নয় - এটি একটি টেবিল। সীমা বাড়ানোর বিষয়ে চিন্তা করার পরিবর্তে স্বার্টের দশ শতাংশের নিয়মটি বিবেচনা করুন : আপনি যদি কোনও এসকিউএল সার্ভারের সীমাতে 10% এর কাছাকাছি পৌঁছে থাকেন তবে আপনি সম্ভবত একটি খারাপ সময় যাচ্ছেন।


1
মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
পল হোয়াইট পুনর্নির্মাণ মনিকা

10

আপনি যদি যাইহোক অ্যাপটি পরিবর্তন করতে চলেছেন তবে তা বিবেচনা করুন

(ক) পুরো মানগুলির জন্য একটি টিভিপি ব্যবহার করে - আপনি DataTableসি # তে একটি তৈরি করে ব্যবহার করে এটি স্টোরেজ পদ্ধতিতে পাস করবেন StructuredType, যেমন আমি এখানে দেখিয়েছি । (আশা করি ১০,০০,০০০ এন্ট্রি স্বাভাবিক নয়, যেহেতু আপনি যে কোনও পদ্ধতির ব্যবহার না করেই স্কেলাবিলিটি সমস্যা হতে পারে))

CREATE TYPE dbo.optionA AS TABLE(value int PRIMARY KEY);
GO

CREATE PROCEDURE dbo.procedure_optionA
  @t dbo.optionA READONLY
AS
BEGIN
  SET NOCOUNT ON;
  SELECT <cols> FROM dbo.<table> AS t
    INNER JOIN @t AS tvp
    ON t.entry = tvp.value;
END
GO

অথবা

(খ) রেঞ্জের উপরের এবং নীচের সীমানায় পাস করার জন্য একটি টিভিপি ব্যবহার করে এবং কিছুটা আলাদা যোগদানের জন্য ধন্যবাদ (ধন্যবাদ @ সাইপারকিউ)।

  CREATE TYPE dbo.optionB AS TABLE
  (
    LowerBound int,
    UpperBound int,
    PRIMARY KEY (LowerBound, UpperBound)
  );
  GO

  CREATE PROCEDURE dbo.procedure_optionB
    @t dbo.OptionB READONLY
  AS
  BEGIN
    SET NOCOUNT ON;
    SELECT <cols> FROM dbo.<table> AS t
      INNER JOIN @t AS tvp
      ON  t.entry >= tvp.LowerBound 
      AND t.entry <= tvp.UpperBound;
  END
  GO

6

না এটি কনফিগারযোগ্য নয় এবং আপনি এটিকে আরও উচ্চতর করে তুলতে পারবেন না।

আপনার উল্লিখিত এমএসডিএন নিবন্ধ এবং অন্যান্য নিবন্ধগুলিতে কার্যত পরামর্শ দেওয়া আছে। আমি এখানে দুটি উল্লেখ করেছি তবে আপনি আরও অনুসন্ধান করতে পারেন।


4

ক্যোয়ারির শর্তটি খাটো করার বিষয়ে কেবল আমার 2 my: -

আপনি যদি আগে থেকে সমস্ত সম্ভাব্য মান নির্ধারণ করতে সক্ষম হন entryতবে আপনি যদি আপনার প্রশ্নের পরিপূরক গ্রহণ করেন তবে এটি কি সম্ভব?

আগে

where entry in (1,2,3,6,7,8,9,10,12,13,15,16,17,18,19,20)

পরে

where entry not in (4,5,11,14)

0

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

  • where entry in (<list of 100.000 values>)দক্ষতা এবং রক্ষণাবেক্ষণের দিক থেকে উভয়ই ব্যবহার করা অত্যন্ত মারাত্মক।
  • ব্যবহার where entry in (select whatever from table)করা আগেরটির মতো সবেমাত্র অত্যাচারজনকভাবে ভয়াবহ। তবুও, আইডিসিএনক্রসি এবং এসকিউএল ইঞ্জিন উভয় টেবিলের উপর নির্ভর করে কর্নিয়া ক্যান্সার সত্ত্বেও এটি ঠিকঠাক সম্পাদন করতে পারে। (ওরাকলে ঠিক থাকতে পারে, মাইএসকিউএল কখনও হবে না, এমএসএসকিউএল সম্পর্কে মনে রাখতে পারে না)।
  • এটি অর্জনের জন্য পিএলএসকিউএল ব্যবহার করা কেবল মারাত্মক।
  • আমার মতে (ক্যোয়ারীটি মোটেও না জেনে), আপনার প্রশ্নের নীচে নিম্নরূপ লিখন করা উচিত:

    • যদি এই 100.000 মানগুলি সর্বদা একই থাকে, বাকী ক্যোয়ারির উপর নির্ভর না করে, আপনার এই মানগুলি একটি সারণীতে (টেবিল_ফিক্সড_মূল্য) আপলোড করতে হবে এবং ব্যবহার করতে হবে

      SELECT * -- whatever you might need
      FROM
         table_a A
         LEFT JOIN table_fixed_values ON A.entry=B.entry
      WHERE B.entry IS NOT NULL
    • যদি 100.000 মানগুলি একই না হয় তবে সেই 100.000 মানগুলি বাছাই করার জন্য কোনও ধরণের যুক্তি থাকতে হবে, যুক্তি যা আপনার ONআগের প্রশ্নের মধ্যে এম্বেড করা উচিত ।


3
কেন LEFT JOIN table_fixed_values ON A.entry=B.entry WHERE B.entry IS NOT NULLএবং সমান, সহজ এবং পড়া সহজ নয় INNER JOIN table_fixed_values ON A.entry=B.entry?
ypercubeᵀᴹ

@ ইয়ার্পেক्यूब - সম্পূর্ণরূপে ঠিক, অভ্যন্তরীণ যোগটি আরও অর্থবোধ করে।
glezo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.