বৃহত টেবিলে যোগদানের অনুকূলিতকরণ


10

আমি million 250 মিলিয়ন ডলারের রেকর্ড সহ একটি টেবিল অ্যাক্সেস করছে এমন একটি ক্যোয়ারির বাইরে আরও কিছু পারফরম্যান্স কোক্সে করার চেষ্টা করছি। বাস্তব প্রয়োগের পরিকল্পনাটি আমার পড়া থেকে, প্রথম বাধা হ'ল এমন একটি কোয়েরি যা দেখে মনে হচ্ছে:

select
    b.stuff,
    a.added,
    a.value
from
    dbo.hugetable a
    inner join
    #smalltable b on a.fk = b.pk
where
    a.added between @start and @end;

জড়িত সারণী ও সূচীর সংজ্ঞাগুলির জন্য আরও নীচে দেখুন।

এক্সিকিউশন প্ল্যান ইঙ্গিত করে যে একটি নেস্টেড লুপটি # স্মার্ট টেবিলের জন্য ব্যবহার করা হচ্ছে এবং হুগেটেবলের উপরের ইনডেক্স স্ক্যানটি 480 বার কার্যকর করা হচ্ছে (প্রতিটি ছোট সারিটির জন্য # ছোট)। এটি আমার কাছে পেছনের দিকে মনে হচ্ছে, সুতরাং আমি পরিবর্তে একটি সংযুক্তি যোগদানের জন্য জোর করে চেষ্টা করার চেষ্টা করেছি:

select
    b.stuff,
    a.added,
    a.value
from
    dbo.hugetable a with(index = ix_hugetable)
    inner merge join
    #smalltable b with(index(1)) on a.fk = b.pk
where
    a.added between @start and @end;

প্রশ্নের সূচক (সম্পূর্ণ সংজ্ঞায়িতের জন্য নীচে দেখুন) কলামগুলি কভার fk (যোগদানের পূর্বাভাস ) কভার করেছে , যোগ করা হয়েছে (যেখানে অনুচ্ছেদে ব্যবহৃত হয়েছে) এবং আইডি (অকেজো) আরোহী ক্রমে, এবং মান অন্তর্ভুক্ত ।

আমি যখন এটি করি, তবে, ক্যোয়ারিটি 2 1/2 মিনিট থেকে 9 এর ওপরে শুরু হয়ে যায় I আমি আশা করতাম যে ইঙ্গিতগুলি আরও দক্ষতার সাথে যোগ দিতে বাধ্য করবে যা প্রতিটি টেবিলের উপরে কেবল একটি পাস করবে, তবে স্পষ্টভাবে নয়।

কোন গাইডেন্স স্বাগত। প্রয়োজনে অতিরিক্ত তথ্য সরবরাহ করা।

আপডেট (2011/06/02)

টেবিলে সূচকগুলি পুনর্গঠিত করে, আমি উল্লেখযোগ্য পারফরম্যান্স ইনড্রোড করেছি, তবে বিশাল টেবিলে ডেটা সংক্ষিপ্ত করার ক্ষেত্রে আমি একটি নতুন বাধা পেয়েছি। ফলাফলটি মাসের দ্বারা সংক্ষিপ্তসার, যা বর্তমানে নীচের মত দেখাচ্ছে:

select
    b.stuff,
    datediff(month, 0, a.added),
    count(a.value),
    sum(case when a.value > 0 else 1 end) -- this triples the running time!
from
    dbo.hugetable a
    inner join
    #smalltable b on a.fk = b.pk
group by
    b.stuff,
    datediff(month, 0, a.added);

বর্তমানে hugetable ক্লাস্টার সূচক আছে pk_hugetable (added, fk)(প্রাথমিক কী), এবং একটি অ-ক্লাস্টার সূচক অন্যান্য উপায় যাচ্ছে ix_hugetable (fk, added)

উপরের চতুর্থ কলাম ব্যতীত, অপটিমাইজারটি বাইরের ইনপুট হিসাবে # স্মার্ট টেবিলটি ব্যবহার করে আগের মতো নেস্টেড লুপ জোড় ব্যবহার করে এবং একটি ক্লাস্টারযুক্ত সূচকটি অভ্যন্তরীণ লুপ হিসাবে সন্ধান করে (আবার 480 বার কার্যকর করে)। আমার সম্পর্কে যা উদ্বেগ তা হ'ল আনুমানিক সারিগুলির মধ্যে বৈষম্য (12,958.4) এবং আসল সারি (74,668,468)। এই সন্ধানগুলির আপেক্ষিক ব্যয় 45%। চলমান সময়টি এক মিনিটের মধ্যেই।

চতুর্থ কলামের সাথে, চলমান সময়টি 4 মিনিট পর্যন্ত বেড়ে যায়। এটি এবার একই আপেক্ষিক ব্যয়ের (৪৫%) ক্লাস্টারড ইনডেক্সে অনুসন্ধান করেছে, একটি হ্যাশ ম্যাচ (৩০%) এর মাধ্যমে সমষ্টি করে, তারপরে একটি হ্যাশ # স্মার্ট টেবিল (0%) এ যোগ দেয়।

আমার পরবর্তী কর্মক্রম সম্পর্কে আমি অনিশ্চিত। আমার উদ্বেগটি হ'ল যে তারিখের সীমা অনুসন্ধান বা যোগদানের প্রাকটিকাকে অবশ্যই গ্যারান্টিযুক্ত নয় এমনকি ফলাফলের সেটটি হ্রাস করতে পারে এমন সমস্ত কিছুর সম্ভাবনা রয়েছে। বেশিরভাগ ক্ষেত্রে তারিখের সীমাটি সম্ভবত 10-15% রেকর্ডগুলি ছাঁটাই করবে এবং fk এ অভ্যন্তরীণ যোগটি সম্ভবত 20-30% ছাঁটাই করতে পারে।


উইল এ দ্বারা অনুরোধ করা হিসাবে, এর ফলাফল sp_spaceused:

name      | rows      | reserved    | data        | index_size  | unused
hugetable | 261774373 | 93552920 KB | 18373816 KB | 75167432 KB | 11672 KB

# স্মার্ট টেবিল হিসাবে সংজ্ঞায়িত করা হয়:

create table #endpoints (
    pk uniqueidentifier primary key clustered,
    stuff varchar(6) null
);

যখন dbo.hugetable হিসাবে সংজ্ঞায়িত করা হয়:

create table dbo.hugetable (
    id uniqueidentifier not null,
    fk uniqueidentifier not null,
    added datetime not null,
    value decimal(13, 3) not null,

    constraint pk_hugetable primary key clustered (
        fk asc,
        added asc,
        id asc
    )
    with (
        pad_index = off, statistics_norecompute = off,
        ignore_dup_key = off, allow_row_locks = on,
        allow_page_locks = on
    )
    on [primary]
)
on [primary];

নিম্নলিখিত সূচক সংজ্ঞায়িত সহ:

create nonclustered index ix_hugetable on dbo.hugetable (
    fk asc, added asc, id asc
) include(value) with (
    pad_index = off, statistics_norecompute = off,
    sort_in_tempdb = off, ignore_dup_key = off,
    drop_existing = off, online = off,
    allow_row_locks = on, allow_page_locks = on
)
on [primary];

আইডি ক্ষেত্র অপ্রয়োজনীয়, একটি পূর্ববর্তী DBA যারা দৃঢ় বিশ্বাস থেকে একটি হস্তনির্মিত বস্তু হল সব টেবিল সর্বত্র একটি GUID, কোন ব্যতিক্রম থাকতে হবে।


দয়া করে আপনি sp_spaceused 'dbo.hugetable' এর ফলাফলটি অন্তর্ভুক্ত করতে পারেন?
হবে যারা একটি

সম্পন্ন হয়েছে, টেবিলের সংজ্ঞা শুরুর ঠিক উপরে জুড়েছে।
কুই জো স্মিথ

এটা নিশ্চিত যে. এর হাস্যকর আকারের কারণেই আমি এটি সন্ধান করছি।
দ্রুত জো স্মিথ

উত্তর:


5

আপনার ix_hugetableদেখতে বেশ অকেজো দেখাচ্ছে কারণ:

  • এটা হল ক্লাস্টার ইনডেক্স (পি কে)
  • ইনক্লুড কোনও পার্থক্য করে না কারণ একটি ক্লাস্টারড ইনডেক্স সমস্ত নন-কী কলামগুলিকে অন্তর্ভুক্ত করে (সর্বনিম্ন পাতায় অ-কী মানগুলি = অন্তর্ভুক্ত = একটি ক্লাস্টার ইনডেক্সটি কী)

এছাড়াও: - যুক্ত বা এফকে প্রথম হওয়া উচিত - আইডি প্রথম হয় = খুব বেশি ব্যবহার হয় না

ক্লাস্টার্ড কীটি এনে (added, fk, id)ড্রপ করার চেষ্টা করুন ix_hugetable। আপনি ইতিমধ্যে চেষ্টা করেছেন (fk, added, id)। অন্য কিছু না হলে, আপনি ডিস্কের অনেক জায়গা এবং সূচী রক্ষণাবেক্ষণ সংরক্ষণ করবেন

অন্য বিকল্পটি হতে পারে টেবিল অর্ডার বোহ উপায়গুলির সাথে ফোর্স অর্ডার ইঙ্গিতটি ব্যবহার করে কোনও জয়েন্ট / আইএনডিএক্স ইঙ্গিত ব্যবহার করা। আমি ব্যক্তিগতভাবে JOIN / INDEX ইঙ্গিতগুলি ব্যবহার না করার চেষ্টা করি কারণ আপনি অপটিমাইজারের জন্য বিকল্পগুলি সরিয়ে দেন। বহু বছর আগে আমাকে বলা হয়েছিল (একটি এসকিউএল গুরু নিয়ে একটি সেমিনার) যে আপনার বিশাল টেবিলটি যখন যোগ করুন ছোট টেবিলটি জোর করুন অর্ডার ইঙ্গিতটি সাহায্য করতে পারে: YMMV 7 বছর পরে ...

ওহ, এবং আমাদের ডিবিএ কোথায় থাকে সে সম্পর্কে আমাদের জানান যাতে আমরা কিছু পারকশন সামঞ্জস্যের ব্যবস্থা করতে পারি

02 জুন আপডেটের পরে সম্পাদনা করুন

চতুর্থ কলামটি ক্লাস্টারযুক্ত সূচকের অংশ নয় তাই এটি ক্লাস্টারড সূচক ব্যবহার করে।

এনসি সূচককে মান কলামে অন্তর্ভুক্ত করার চেষ্টা করুন যাতে এটি ক্লাস্টারড ইনডেক্সের মান কলামটি অ্যাক্সেস করতে না পারে

create nonclustered index ix_hugetable on dbo.hugetable (
    fk asc, added asc
) include(value)

দ্রষ্টব্য: মানটি যদি অযোগ্য হয় না তবে এটি COUNT(*)শব্দার্থগতভাবে একই । তবে এসইউমের জন্য এটির আসল মান প্রয়োজন , অস্তিত্ব নয় ।

উদাহরণস্বরূপ, যদি আপনি পরিবর্তন COUNT(value)করতে COUNT(DISTINCT value) থাকলে সূচক পরিবর্তন এটা ক্যোয়ারী আবার কারণ এটি একটি মান হিসাবে মান প্রক্রিয়া আছে, না অস্তিত্ব যেমন ভঙ্গ করা উচিত নয়।

ক্যোয়ারিতে 3 টি কলাম দরকার: যুক্ত, এফ, মান। প্রথম 2 ফিল্টার করা হয়েছে / যোগদান করেছে তাই কী কলামগুলি। মানটি ব্যবহৃত হয় তাই অন্তর্ভুক্ত করা যায়। একটি আচ্ছাদন সূচকের ক্লাসিক ব্যবহার।


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

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

@ কিউক জো স্মিথ: আমার উত্তর আপডেট করেছেন
gbn

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

2

hugetableশুধু addedকলামে একটি সূচক সংজ্ঞা দিন ।

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


এক্সিকিউশন প্ল্যান দেখায় যে সূচি (ix_hugetable) সন্ধান করা হচ্ছে। বা আপনি কি বলছেন যে এই সূচিটি ক্যোয়ারের জন্য উপযুক্ত নয়?
দ্রুত জো স্মিথ

সূচকটি উপযুক্ত নয়। এটি কীভাবে "সূচকটি ব্যবহার করছে" কে জানে। অভিজ্ঞতা আমাকে বলে যে এটি আপনার সমস্যা। এটি ব্যবহার করে দেখুন এবং এটি কীভাবে চলে তা আমাদের জানান।
বোহেমিয়ান

@ কিউইক জো স্মিথ - আপনি কি বোহেমিয়ার পরামর্শটি চেষ্টা করেছিলেন? ফলাফল কোথায়?
লিভেন কের্মসেকারগণ

2
আমি অসম্মতি: অন ক্লজটি প্রথমে যৌক্তিকভাবে প্রথমে প্রক্রিয়াজাত হয় এবং কার্যকরভাবে এটি একটি বাস্তবে কার্যকর যেখানে ওপিকে প্রথমে উভয় কলাম চেষ্টা করতে হবে। JOIN এর জন্য fk মান পাওয়ার জন্য এফকে তেমন কোনও ইন্ডেক্সডিং নয় = ক্লাস্টারড ইনডেক্স স্ক্যান বা কী লুকআপ। আপনি যে আচরণটি খুব বর্ণনা করেছেন তাতে কি কিছু উল্লেখ যুক্ত করতে পারেন? বিশেষত এসকিউএল সার্ভারের জন্য আপনার এই আরডিবিএমএসের জন্য পূর্ববর্তী ইতিহাসের সামান্য উত্তর দেওয়া হয়েছে। আসলে, -১
এআই

2

এক্সিকিউশন প্ল্যান ইঙ্গিত করে যে একটি নেস্টেড লুপটি # স্মার্ট টেবিলের জন্য ব্যবহার করা হচ্ছে এবং হুগেটেবলের উপরের ইনডেক্স স্ক্যানটি 480 বার কার্যকর করা হচ্ছে (প্রতিটি ছোট সারিটির জন্য # ছোট)।

লুপটি সঠিক পছন্দে যোগ দেবে এই ধারণা করেই আমি ক্যোরি অপটিমাইজারটি ব্যবহার করার প্রত্যাশা করেছিলাম order বিকল্পটি 250M বার লুপ করা এবং প্রতিবার # টেম্প টেবিলে একটি অনুসন্ধান করা - যা বেশ কয়েক ঘন্টা / দিন সময় নিতে পারে।

সূচক আপনি অত্যাচার করছি একত্রীকরণ ব্যবহৃত করা যোগদান প্রায় কাছাকাছি 250M সারি * 'প্রতিটি সারির আকার' - ছোট না, এ অন্তত গিগাবাইট একটি দম্পতি। sp_spaceused'কয়েক গিগাবাইট' আউটপুট থেকে বিচার করা সম্ভবত একটি সংক্ষিপ্ত বিবরণ হতে পারে - মার্জ যোগ দেওয়ার জন্য আপনাকে সূচীর মধ্য দিয়ে ট্রল করতে হবে যা খুব I / O নিবিড় হতে চলেছে।


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

2
তবে এর চেয়ে আরও কিছু আছে। # স্মার্ট টেবিলের যদি প্রচুর পরিমাণে সারি থাকে তবে একত্রিত হওয়া সংযুক্তি যথাযথ হতে পারে। যদি এর নাম অনুসারে, এর মধ্যে কয়েকটি সংখ্যক সারি থাকে তবে একটি লুপ জোড় সঠিক পছন্দ হতে পারে। কল্পনা করুন যে # স্মার্ট টেবিলের একটি বা দুটি সারি ছিল এবং অন্য টেবিল থেকে বনাম বনাম কয়েকটি মুখ্য সারি মিলিয়েছে - এখানে একত্রিত হওয়া সংযোজনকে ন্যায়সঙ্গত করা শক্ত হবে hard
উইল হবে

আমি বুঝতে পেরেছি এটি আরও ছিল; আমি জানি না যে এটি কি হতে পারে। ডাটাবেস অপ্টিমাইজেশন হুবহু আমার দৃ strong় মামলা নয়, আপনি সম্ভবত ইতিমধ্যে অনুমান করেছেন।
কুই জো স্মিথ

@ কিউক জো স্মিথ - এসপি_স্পেসেসের জন্য ধন্যবাদ। 75 জিবি সূচক এবং 18 জিবি ডেটা - ix_hugetable কি টেবিলের একমাত্র সূচক নয়?
হবে যারা একটি

1
+1 উইল। পরিকল্পনাকারী বর্তমানে সঠিক কাজ করছেন। আপনার টেবিলগুলি ক্লাস্টার করার কারণে সমস্যাটি এলোমেলো ডিস্কের মধ্যে রয়েছে।
ডেনিস ডি বার্নার্ডি

1

আপনার সূচকটি ভুল। দেখুন ইনডেক্স ডস এবং donts

জিনিসগুলি দাঁড়ানোর সাথে সাথে আপনার একমাত্র দরকারী সূচকটি হ'ল ছোট টেবিলের প্রাথমিক কী। একমাত্র যুক্তিসঙ্গত পরিকল্পনা হ'ল ছোট টেবিলটি স্ক্যান করা এবং বিশালটি দিয়ে গণ্ডগোল লুপ করা।

একটি ক্লাস্টার ইনডেক্স যোগ করার চেষ্টা করুন hugetable(added, fk)। এটি পরিকল্পনাকারীর পক্ষে বিশাল টেবিল থেকে প্রযোজ্য সারিগুলি সন্ধান করা এবং নীড়ের লুপ বা ছোট টেবিলের সাথে তাদের সংযুক্ত হওয়া উচিত।


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