বিচ্ছিন্নতার সাথে দক্ষতার সাথে বড় আকারের ফিল্টার করুন


9

ধরা যাক আমার একটি টেবিল আছে

CREATE TABLE Ticket (
    TicketId int NOT NULL,
    InsertDateTime datetime NOT NULL,
    SiteId int NOT NULL,
    StatusId tinyint NOT NULL,
    AssignedId int NULL,
    ReportedById int NOT NULL,
    CategoryId int NULL
);

এই উদাহরণে TicketIdপ্রাথমিক কী।

আমি চাই যে ব্যবহারকারীরা এই সারণির বিপরীতে "আংশিকভাবে অ্যাড-হক" অনুসন্ধান তৈরি করতে সক্ষম হন। আমি আংশিক বলেছি কারণ প্রশ্নের কিছু অংশ সর্বদা স্থির থাকবে:

  1. কোয়েরিটি সর্বদা একটিতে একটি ব্যাপ্তি ফিল্টার সম্পাদন করবেInsertDateTime
  2. কোয়েরিটি সর্বদা থাকবে ORDER BY InsertDateTime DESC
  3. ক্যোয়ারী পৃষ্ঠা ফলাফল করবে

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

SELECT
    TicketId
FROM (
    SELECT
        TicketId,
        ROW_NUMBER() OVER(ORDER BY InsertDateTime DESC) as RowNum
    FROM Ticket
    WHERE InsertDateTime >= '2013-01-01' AND InsertDateTime < '2013-02-01'
      AND StatusId IN (1,2,3)
      AND (CategoryId IN (10,11) OR CategoryId IS NULL)
    ) _
WHERE RowNum BETWEEN 1 AND 100;

এখন ধরে নিন টেবিলটিতে 100,000,000 সারি রয়েছে।

আমি যে সেরাটি সামনে আসতে পারি তা হ'ল একটি কভারিং সূচক যা প্রতিটি "optionচ্ছিক" কলামকে অন্তর্ভুক্ত করে:

CREATE NONCLUSTERED INDEX IX_Ticket_Covering ON Ticket (
    InsertDateTime DESC
) INCLUDE (
    SiteId, StatusId, AssignedId, ReportedById, CategoryId
);

এটি আমাকে নীচে একটি কোয়েরি পরিকল্পনা দেয়:

  • নির্বাচন
    • ছাঁকনি
      • শীর্ষ
        • সিকোয়েন্স প্রকল্প (গণনা স্কেলার)
          • অংশ
            • সূচি সন্ধান করুন

বেশ ভাল লাগছে। প্রায় 80% -90% ব্যয় সূচক সিক অপারেশন থেকে আসে যা আদর্শ।

এই জাতীয় অনুসন্ধান কার্যকর করার জন্য আরও ভাল কৌশল আছে কি?

অগত্যা আমি ক্লায়েন্টের কাছে alচ্ছিক ফিল্টারিং অফলোড করতে চাই না কারণ কিছু ক্ষেত্রে "স্থির" অংশ থেকে ফলাফল সেট করা 100s বা অধিকার হতে পারে। ক্লায়েন্ট তার পরে বাছাই এবং পেজিংয়ের জন্যও দায়ী, যা ক্লায়েন্টের পক্ষে খুব বেশি কাজ করতে পারে।


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

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

স্টোরেজ স্পেস ব্যবহার করার বিষয়ে আপনি কতটা যত্নবান?
জন সেগেল

@ জোনসিগেল এটি কতটা তার উপর নির্ভর করে ... তবে আমি কোনও পরামর্শ দেখতে চাই
জোসেফ ডাইগল

2
এবং ফলাফলগুলির ২ য় পৃষ্ঠা পেতে আপনার দৃষ্টিভঙ্গি / ক্যোয়ারীটি কী? RowNum BETWEEN 101 AND 200?
ypercubeᵀᴹ

উত্তর:


1

যদি এই নির্দিষ্ট কাজের বোঝাটি সারণীর বিপরীতে বেশিরভাগ প্রশ্নের হয় তবে আপনি বিবেচনা করতে পারেন:

ALTER TABLE Ticket ADD CONSTRAINT PK_Ticket PRIMARY KEY NONCLUSTERED (TicketId);

CREATE UNIQUE CLUSTERED INDEX IX_Ticket_Covering ON Ticket (
    InsertDateTime ASC
);

বিবেচ্য বিষয়:

  • আপনি ডেটটাইম 2 (এসকিউএল ২০০+; নমনীয় নির্ভুলতা) ব্যবহার করতে পারেন
  • InsertDateTime আপনার নির্ভুলতার মধ্যে অনন্য হবে
  • সময়গুলি সীমাবদ্ধ না রাখলে অনন্য এসকিউএল প্রকারের একটি গোপন ইউনিকফায়ার কলাম যুক্ত করবে। এটি সমস্ত অবিচ্ছিন্ন সূচকে যুক্ত করা হয়েছে যাতে তারা সঠিক ক্লাস্টারযুক্ত রেকর্ডটি উল্লেখ করতে পারে

সুবিধাদি:

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

1

আমি অতীতে এই কৌশলটি ব্যবহার করেছি। টেবিলটি প্রায় তেমন বড় ছিল না তবে অনুসন্ধানের মানদণ্ডটি আরও জটিল।

এটি সংক্ষিপ্ত সংস্করণ।

CREATE PROC usp_Search
    (
    @StartDate  Date,
    @EndDate    Date,
    @Sites      Varchar(30) = NULL,
    @Assigned   Int = NULL, --Assuming only value possible
    @StartRow   Int,
    @EndRow     Int
    )
AS
DECLARE @TblSites   TABLE (ID Int)
IF @Sites IS NOT NULL
BEGIN
    -- Split @Sites into table @TblSites
END
SELECT  TicketId
FROM    (
        SELECT  TicketId,
                ROW_NUMBER() OVER(ORDER BY InsertDateTime DESC) as RowNum
        FROM    Ticket
                LEFT JOIN @TblSites
                    Ticket.SiteID = @TblSites.ID
        WHERE   InsertDateTime >= @StartDate 
                AND InsertDateTime < @EndDate
                AND (
                    @Assigned IS NULL 
                    OR AssignedId = @Assigned 
                    )
        ) _
WHERE   RowNum BETWEEN @StartRow AND @EndRow;

1

আপনার প্রথম দুটি পূর্বশর্ত দেওয়া আমি একটি ক্লাস্টারড সূচকটি দেখছি InsertDateTime


0

আপনি বিভাজন বিবেচনা করবেন না কেন? এটি এসকিউএল ২০০৮ এ উপরের দিকে উপলভ্য তবে এন্টারপ্রাইজ সংস্করণ (বা বিকাশকারী সংস্করণ) প্রয়োজন।

মূলত, আপনি একাধিক পার্টিশন জুড়ে আপনার টেবিলকে বিভক্ত করেছেন এবং আপনি নিজের পার্টিশন মানদণ্ড (ফাংশন) সংজ্ঞায়িত করেন আপনার তারিখের সীমা হবে?

https://www.simple-talk.com/sql/database-administration/gail-shaws-sql-server-howlers/


-1

যদি ক্লায়েন্টরা প্রায় একইভাবে বারবার ফিল্টার করে থাকে তবে আপনি এই প্রশ্নের জন্য একটি সূচক তৈরি করতে পারেন।

যেমন ক্লায়েন্টটি সাইটআইড এবং স্থিতিতে ফিল্টার করছে আপনি অতিরিক্ত সূচক তৈরি করতে পারেন:

CREATE NONCLUSTERED INDEX IX_Ticket_InsertDateTime_SiteId_StatusId ON Ticket     
(InsertDateTime DESC,
 SiteId [ASC/DESC],
 StatusId [ASC/DESC] ) 
 INCLUDE ( ... );

এইভাবে, বেশিরভাগ 'বেশি সাধারণ' অনুসন্ধানগুলি দ্রুত চলতে পারে।

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