যদি উপস্থিত থাকে তবে ক্যারিয়ার মোড়ক এটিকে খুব ধীর করে তোলে


16

আমার নীচের কোয়েরি রয়েছে:

select databasename 
from somedb.dbo.bigtable l where databasename ='someval' and source  <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)

উপরের প্রশ্নটি তিন সেকেন্ডে সম্পূর্ণ হয়।

যদি উপরের ক্যোয়ারী কোনও মান দেয় তবে আমরা সঞ্চিত পদ্ধতিটি প্রস্থান করতে চাই, তাই আমি নীচের মতো এটি আবার লিখেছি:

If Exists(
select databasename 
from somedb.dbo.bigtable l where databasename ='someval' and source  <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source)
)
Begin
Raiserror('Source missing',16,1)
Return
End

তবে এটি 10 ​​মিনিট সময় নিচ্ছে।

আমি নীচের মত উপরের ক্যোয়ারীটি আবার লিখতে পারি, যা 3 সেকেন্ডেরও কম সময়ে পূর্ণ হয়:

  select databasename 
from somedb.dbo.bigtable l where databasename ='someval' and source  <>'kt'
and not exists(select 1 from dbo.smalltable c where c.source=l.source
if @@rowcount >0
Begin
Raiserror('Source missing',16,1)
Return
End

উপরের পুনর্লিখনের বিষয়টি হ'ল উপরের ক্যোয়ারীটি বৃহত সঞ্চিত পদ্ধতির অংশ এবং এটি একাধিক ফলাফল সেটগুলি দেয়। সি # তে, আমরা প্রতিটি ফলাফলের সেটটি দিয়ে পুনরাবৃত্তি করি এবং কিছু প্রক্রিয়াজাত করি।

উপরেরটি একটি খালি ফলাফলের সেট দেয়, সুতরাং আমি যদি এই পদ্ধতির সাথে যাই তবে আমাকে আমার সি # পরিবর্তন করতে হবে এবং আবার স্থাপনা করতে হবে।

আমার প্রশ্নটি হ'ল

কেন কেবলমাত্র IF EXISTSএত বেশি সময় নেওয়ার পরিকল্পনা পরিবর্তিত হয়?

নীচে বিশদগুলি যা আপনাকে সহায়তা করতে পারে এবং আপনার যদি কোনও বিবরণ প্রয়োজন হয় তবে আমাকে জানান:

  1. খনি হিসাবে একই পরিকল্পনা পেতে সারণী এবং পরিসংখ্যান স্ক্রিপ্ট তৈরি করুন
  2. স্লো এক্সিকিউশন প্ল্যান
  3. দ্রুত কার্যকর করার পরিকল্পনা

    ব্রেন্টোজার ব্যবহার করে ধীরগতির পরিকল্পনাটি বেন্টুজার পেস্ট করে প্ল্যান্ট
    প্ল্যান করুন প্লাস্টিকটি ফাস্ট প্ল্যান করুন

দ্রষ্টব্য: উভয় প্রশ্ন একই (পরামিতি ব্যবহার করে), একমাত্র পার্থক্য EXISTS(যদিও বেনাম বানাতে গিয়ে আমি কিছু ভুল করে থাকতে পারি)।

সারণী তৈরির স্ক্রিপ্টগুলি নীচে রয়েছে:

http://pastebin.com/CgSHeqXc - ছোট টেবিলের পরিসংখ্যান
http://pastebin.com/GUu9KfpS - বড় টেবিলের পরিসংখ্যান


উত্তর:


18

দ্বারা ব্যাখ্যা করা হয়েছে হিসাবে পল হোয়াইট : তার ব্লগ পোস্টে ইনসাইড অপ্টিমাইজার: ROW গোল ইন ডেপথEXISTS প্রবর্তন একটি সারিতে লক্ষ্য, যা পছন্দ NESTED LOOPSবা MERGE JOINওভারHASH MATCH

একটি চূড়ান্ত উদাহরণ হিসাবে, বিবেচনা করুন যে লজিকাল আধা-যোগ (যেমন EXISS এর সাথে উপস্থাপিত উপ-কোয়েরি) সামগ্রিক থিমটি ভাগ করে নেয়: এটি প্রথম মিলের সারিটি দ্রুত খুঁজে পাওয়ার জন্য অনুকূলিত হওয়া উচিত।

আপনার ক্যোয়ারিতে এটি স্পষ্টতই নেস্টেড লুপগুলি প্রবর্তন এবং সমান্তরালতা সরিয়ে ফেলতে হবে, যার ফলে ধীরগতির পরিকল্পনা হয়।

সুতরাং আপনার কোয়েরিটি ব্যবহার না করেই সম্ভবত আপনার ক্যোয়ারীটি পুনরায় লেখার কোনও উপায় খুঁজে বের করতে হবে NOT EXISTS

আপনি আপনার ক্যোয়ারীটি পুনরায় LEFT OUTER JOINলেখার মাধ্যমে সরে যেতে পারেন এবং পরীক্ষা করে ছোট্ট টেবিলের কোনও সারি নেই তা পরীক্ষা করে checkingNULL

If EXISTS(
    SELECT databasename
    FROM somedb.dbo.bigtable l
    LEFT JOIN dbo.smalltable c ON c.source = l.source
    WHERE databasename = 'someval'
    AND source <> 'kt'
    AND c.source IS NULL
)

EXCEPTএই ক্ষেত্রের সাথে আপনার কতগুলি ক্ষেত্রের তুলনা করতে হবে তার উপর নির্ভর করে আপনি সম্ভবত একটি ক্যোরিও ব্যবহার করতে পারেন :

If EXISTS(
   SELECT source
   FROM somedb.dbo.bigtable l
   WHERE databasename = 'someval'
   AND source <> 'kt'

   EXCEPT

   SELECT source
   FROM dbo.smalltable
)

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

সম্পর্কিত প্রশ্নোত্তর: যদি এম্বেড করা নির্বাচনী বিবৃতিটির চেয়ে বেশি সময় নেয় তবে


0

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

If not exists(
    select databasename 
    from somedb.dbo.bigtable l
    inner hash join dbo.smalltable c 
        on c.source = l.source
where databasename ='someval' and source  <>'kt')
begin
    Raiserror('Source missing',16,1)
    Return
end

উপস্থিত থাকা বা না থাকা ব্যবহারের সময় এসকিউএল সার্ভারটি নিসটেড লুপ অপারেশন সহ কোয়েরি প্ল্যান উত্পন্ন করে ধরে নিয়েছে যে শর্তটি পূরণ করার জন্য এটি প্রথম সারির সন্ধানে এক এক করে সেট এর সমস্ত সারি পেরিয়ে যাবে। HASH JOIN ব্যবহার করা এটির গতি বাড়িয়ে দেবে।


আপনার চেয়ে, এটি পরীক্ষা করবে
TheGameiswar

0

আমি একই ইস্যুটি নিয়ে এসেছি, "উপস্থিতি" ব্যবহার এড়িয়ে এবং "COUNT ()" ফাংশন এবং "আইএফ ... ইএলএসই" বিবৃতিটি ব্যবহার করে আমি নিজেকে কাজ করার ব্যবস্থা করেছি।

আপনার উদাহরণের জন্য নিম্নলিখিত চেষ্টা করুন:

IF
(
    SELECT
        COUNT(l.databasename) + 1 AS databasename
    FROM somedb.dbo.bigtable AS l

    WHERE   l.databasename ='someval'
        AND l.[source]  <> 'kt'
        AND NOT EXISTS(SELECT 1 FROM dbo.smalltable AS c WHERE c.[source]=l.[source])
) > 1 --Acts like EXISTS
BEGIN
    RAISERROR('Source missing', 16, 1)
RETURN
END

আমি কাউন্টে "+ 1" যুক্ত করার কারণটি হ'ল আমি যদি "> 1" আইএফ অবস্থায় ব্যবহার করতে পারি তবে "> 0" বা "<> 0" ব্যবহার করে প্রশ্নটি HASH এর পরিবর্তে নেস্টেড লুপগুলি ব্যবহার করতে ট্রিগার করবে ম্যাচ. কেন এমনটি ঘটছে তা কেন খুঁজে পাওয়া আকর্ষণীয় হবে তা কেন দেখেননি।

আশা করি এইটি কাজ করবে!

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