তারিখের সীমা পুনরুদ্ধার করার সর্বাধিক দক্ষ উপায়


16

এই জাতীয় সারণির কাঠামোর সাথে তারিখের সীমাগুলি পুনরুদ্ধার করার সবচেয়ে কার্যকরী উপায় কী?

create table SomeDateTable
(
    id int identity(1, 1) not null,
    StartDate datetime not null,
    EndDate datetime not null
)
go

বলুন আপনি StartDateএবং উভয়ের জন্য একটি পরিসর চান EndDate। তাই অন্য কথায়, যদি StartDateমধ্যে পড়ে @StartDateBeginএবং @StartDateEnd, এবং EndDateমধ্যে পড়ে @EndDateBeginএবং @EndDateEndতারপর, কিছু করতে।

আমি জানি সম্ভবত এটি সম্পর্কে আরও কয়েকটি উপায় আছে তবে সবচেয়ে পরামর্শ দেওয়া কী?

উত্তর:


29

এটি সাধারণভাবে সমাধান করা একটি কঠিন সমস্যা, তবে অপটিমাইজার একটি পরিকল্পনা বেছে নিতে সহায়তা করতে আমরা কয়েকটি জিনিস করতে পারি। এই স্ক্রিপ্টটি 10,000 টি সারি দিয়ে একটি সারণী তৈরি করে যা সুনির্দিষ্ট ছদ্ম-এলোমেলো বন্টন সারণীর বর্ণনা সহ:

CREATE TABLE dbo.SomeDateTable
(
    Id          INTEGER IDENTITY(1, 1) PRIMARY KEY NOT NULL,
    StartDate   DATETIME NOT NULL,
    EndDate     DATETIME NOT NULL
);
GO
SET STATISTICS XML OFF
SET NOCOUNT ON;
DECLARE
    @i  INTEGER = 1,
    @s  FLOAT = RAND(20120104),
    @e  FLOAT = RAND();

WHILE @i <= 10000
BEGIN
    INSERT dbo.SomeDateTable
        (
        StartDate, 
        EndDate
        )
    VALUES
        (
        DATEADD(DAY, @s * 365, {d '2009-01-01'}),
        DATEADD(DAY, @s * 365 + @e * 14, {d '2009-01-01'})
        )

    SELECT
        @s = RAND(),
        @e = RAND(),
        @i += 1
END

প্রথম প্রশ্নটি হল এই টেবিলটি কীভাবে সূচক করা যায়। একটি বিকল্প দুটি ইনডেক্স প্রদান করা হয় DATETIME, কলাম তাই অপটিমাইজার অন্তত উপর চাইতে হবে কিনা তা নির্বাচন করতে পারবেন StartDateবা EndDate

CREATE INDEX nc1 ON dbo.SomeDateTable (StartDate, EndDate)
CREATE INDEX nc2 ON dbo.SomeDateTable (EndDate, StartDate)

স্বাভাবিকভাবেই, উভয় ক্ষেত্রেই অসমতা StartDateএবং এর EndDateঅর্থ হ'ল প্রতিটি সূচকের কেবল একটি কলাম উদাহরণ ক্যোয়ারির অন্বেষণকে সমর্থন করতে পারে, তবে এটি আমাদের পক্ষে সবচেয়ে ভাল। আমরা প্রতিটি সূচকে দ্বিতীয় কলামটি INCLUDEকী-এর পরিবর্তে তৈরি করার বিষয়টি বিবেচনা করতে পারি, তবে আমাদের অন্যান্য প্রশ্ন থাকতে পারে যা নেতৃস্থানীয় কলামে সাম্যতা এবং দ্বিতীয় কলামে অসমতার সন্ধান করতে পারে। এছাড়াও, আমরা এইভাবে আরও ভাল পরিসংখ্যান পেতে পারি। যাই হোক ...

DECLARE
    @StartDateBegin DATETIME = {d '2009-08-01'},
    @StartDateEnd DATETIME = {d '2009-10-15'},
    @EndDateBegin DATETIME = {d '2009-08-05'},
    @EndDateEnd DATETIME = {d '2009-10-22'}

SELECT
    COUNT_BIG(*)
FROM dbo.SomeDateTable AS sdt
WHERE
    sdt.StartDate BETWEEN @StartDateBegin AND @StartDateEnd
    AND sdt.EndDate BETWEEN @EndDateBegin AND @EndDateEnd

এই ক্যোয়ারীটি ভেরিয়েবলগুলি ব্যবহার করে, তাই সাধারণভাবে অপটিমাইজারটি নির্বাচন এবং বিতরণে অনুমান করবে, ফলস্বরূপ 81 টি সারির অনুমানযুক্ত কার্ডিনালিটির অনুমান । আসলে, ক্যোয়ারী 2076 টি সারি তৈরি করে, একটি তাত্পর্য যা আরও জটিল উদাহরণে গুরুত্বপূর্ণ হতে পারে।

এসকিউএল সার্ভার 2008 এসপি 1 CU5 বা পরে (অথবা R2 হলো RTM CU1) আমরা সুবিধা গ্রহণ করতে পারেন প্যারামিটার এমবেডিং অপ্টিমাইজেশান ভাল অনুমান করতে, খালি যোগ করে OPTION (RECOMPILE)করতে SELECTউপরে জিজ্ঞাস্য। এটি ব্যাচ কার্যকর হওয়ার ঠিক আগে সংকলন সৃষ্টি করে, এসকিউএল সার্ভারকে আসল প্যারামিটারের মানগুলি 'দেখতে' দেয় এবং সেগুলির জন্য অনুকূলিত করে। এই পরিবর্তনের সাথে সাথে অনুমানটি 468 টি সারিতে উন্নত হয় (যদিও এটি দেখার জন্য আপনাকে রানটাইম পরিকল্পনাটি পরীক্ষা করা দরকার)। এই অনুমানটি 81 টি সারির চেয়ে ভাল তবে এখনও এটি খুব কাছে নয়। ট্রেস পতাকা 2301 দ্বারা সক্ষম হওয়া মডেলিং এক্সটেনশানগুলি কিছু ক্ষেত্রে সহায়তা করতে পারে তবে এই ক্যোয়ারির সাথে নয়।

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

SELECT COUNT(*) FROM
(
    SELECT
        sdt.Id
    FROM dbo.SomeDateTable AS sdt
    WHERE 
        sdt.StartDate BETWEEN @StartDateBegin AND @StartDateEnd
    INTERSECT
    SELECT
        sdt.Id
    FROM dbo.SomeDateTable AS sdt 
    WHERE
        sdt.EndDate BETWEEN @EndDateBegin AND @EndDateEnd
) AS intersected (id)
OPTION (RECOMPILE)

এই ফর্মটি 2110 সারিগুলির একটি রানটাইমের প্রাক্কলন ঘটায় (2076 আসল বিপরীতে)। আপনার যদি টিএফ 2301 না থাকে তবে সেক্ষেত্রে আরও উন্নত মডেলিং কৌশলগুলি কৌশলটি দেখে এবং ঠিক আগের মতোই প্রাক্কলন উত্পাদন করে: 468 সারি।

একদিন এসকিউএল সার্ভার অন্তরগুলির জন্য স্থানীয় সমর্থন অর্জন করতে পারে। যদি এটির পরিসংখ্যানগত সমর্থনটি আসে তবে বিকাশকারীরা এই জাতীয় ক্যোয়ারী পরিকল্পনাগুলিকে কিছুটা কমই ভয় করতে পারে।


5

আমি এমন কোনও সমাধান জানি না যা সমস্ত ডেটা বিতরণের জন্য দ্রুত, তবে যদি আপনার সমস্ত ব্যাপ্তি সংক্ষিপ্ত হয়, আমরা সাধারণত এটি দ্রুত করতে পারি। উদাহরণস্বরূপ, যদি এই ক্যোয়ারির পরিবর্তে ব্যাপ্তি এক দিনের চেয়ে কম হয়:

SELECT  TaskId ,    
        TaskDescription ,
        StartedAt ,    
        FinishedAt    
FROM    dbo.Tasks    
WHERE   '20101203' BETWEEN StartedAt AND FinishedAt

আমরা আরও একটি শর্ত যুক্ত করতে পারি:

SELECT  TaskId ,    
        TaskDescription ,
        StartedAt ,    
        FinishedAt    
FROM    dbo.Tasks    
WHERE   '20101203' BETWEEN StartedAt AND FinishedAt
    AND StartedAt >= '20101202'
    AND FinishedAt <= '20101204' ;

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

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