ক্রমাগত প্রক্রিয়া চলাকালীন সূচক বিভাজন


10

এসকিউএল সার্ভার 2005

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

/**************************************/
CREATE TABLE [Table] 
(
    [PrimaryKeyId] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
    [ForeignKeyId] [INT] NOT NULL,
    /* more columns ... */
    [DataType] [CHAR](1) NOT NULL,
    [DataStatus] [DATETIME] NULL,
    [ProcessDate] [DATETIME] NOT NULL,
    [ProcessThreadId] VARCHAR (100) NULL
);

CREATE NONCLUSTERED INDEX [Idx] ON [Table] 
(
    [DataType],
    [DataStatus],
    [ProcessDate],
    [ProcessThreadId]
);
/**************************************/

/**************************************/
WITH cte AS (
    SELECT TOP (@BatchSize) [PrimaryKeyId], [ProcessThreadId]
    FROM [Table] WITH ( ROWLOCK, UPDLOCK, READPAST )
    WHERE [DataType] = 'X'
    AND [DataStatus] IS NULL
    AND [ProcessDate] < DATEADD(m, -2, GETDATE()) -- older than 2 months
    AND [ProcessThreadId] IS NULL
)
UPDATE cte
SET [ProcessThreadId] = @ProcessThreadId;

SELECT * FROM [Table] WITH ( NOLOCK )
WHERE [ProcessThreadId] = @ProcessThreadId;
/**************************************/

ডেটা বিষয়বস্তু ...
কলাম [ডেটাটাইপ] CHAR (1) হিসাবে টাইপ করা হয়, সমস্ত রেকর্ডের প্রায় 35% 'এক্স' এর সাথে অবশিষ্ট 'এ' এর সমান হয়।
কেবলমাত্র রেকর্ডগুলির মধ্যে যেখানে [ডেটাটাইপ] 'এক্স' এর সমান হয়, প্রায় 10% এর একটি নট [ডাটাস্ট্যাটাস] মান থাকবে।

[প্রসেসডেট] এবং [প্রক্রিয়াজাতকরণ] কলামগুলি প্রতিটি প্রক্রিয়াজাত রেকর্ডের জন্য আপডেট করা হবে।
[ডেটা টাইপ] কলামটি আপডেট করা হয় ('এক্স' পরিবর্তন করে 'এ' তে পরিণত হয়) প্রায় 10% সময়।
[ডেটাস্ট্যাটাস] কলামটি 1% এরও কম সময় আপডেট হয়।

আপাতত আমার সমাধানটি হ'ল পৃথক প্রক্রিয়াকরণ সারণিতে প্রক্রিয়া করার জন্য সমস্ত রেকর্ডের প্রাথমিক কী নির্বাচন করা। আমি কীগুলি সেগুলি প্রসেস করার সাথে সাথে মুছে ফেলি যাতে সূচি খণ্ড হিসাবে আমি কম রেকর্ড নিয়ে কাজ করছি।

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

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


একটি ধারণাও: আপনার সূচকটি ভুল ক্রম হিসাবে উপস্থিত বলে মনে হচ্ছে: এটি সর্বাধিক নির্বাচনী থেকে কমপক্ষে নির্বাচক হওয়া উচিত। তাহলে প্রসেসথ্রেডআইড, প্রসেসডেট, ডেটাস্ট্যাটাস, ডেটাটাইপ সম্ভবত?
gbn

আমরা আমাদের চ্যাটে এটি বিজ্ঞাপন দিয়েছি। খুব ভাল প্রশ্ন। chat.stackexchange.com/rooms/179/the-heap
gbn

আমি নির্বাচনের আরও সঠিক প্রতিনিধিত্ব হতে ক্যোয়ারী আপডেট করেছি। আমি এটি চালাচ্ছি একাধিক সমবর্তী থ্রেড। আমি নির্বাচনী আদেশের সুপারিশটি নোট করেছি। ধন্যবাদ।
ক্রিস গ্যালুচি

@ ক্রিসগ্যালুচি আপনি যদি পারেন তবে চ্যাট করতে আসুন ...
জেএনকে

উত্তর:


4

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

ধাঁধাটির আর একটি গুরুত্বপূর্ণ অংশ হ'ল প্রক্রিয়া চলাকালীন সারির আকারটি ধ্রুবক রাখা। আপনি ঘোষণা করেছেন ProcessThreadIdহিসেবে VARCHAR(100)যা সারি বোঝা বাড়া এবং কমা যেমন হচ্ছে 'প্রক্রিয়াজাত' কারণ ক্ষেত্রের মান অ নাল করার শূন্য থেকে পরিবর্তন করে। এই সারিতে ক্রমবর্ধমান-সঙ্কুচিত প্যাটার্নটির ফলে পৃষ্ঠা বিভাজন এবং বিভাজন ঘটে। আমি সম্ভবত 'থ্রোড আইডি' কল্পনা করতে পারি না যা 'ভারচার (100)'। একটি নির্দিষ্ট দৈর্ঘ্যের ধরণ ব্যবহার করুন, সম্ভবত একটি INT

পার্শ্ব নোট হিসাবে, আপনাকে দুটি ধাপে ছাড়ার প্রয়োজন হবে না (আপডেটের পরে নির্বাচন নির্বাচন করুন)। উপরে লিঙ্ক করা নিবন্ধে বর্ণিত হিসাবে আপনি OUTPUT ধারাটি ব্যবহার করতে পারেন:

/**************************************/
CREATE TABLE [Table] 
(
    [PrimaryKeyId] [INT] IDENTITY(1,1) NOT NULL PRIMARY KEY NONCLUSTERED,
    [ForeignKeyId] [INT] NOT NULL,
    /* more columns ... */
    [DataType] [CHAR](1) NOT NULL,
    [DataStatus] [DATETIME] NULL,
    [ProcessDate] [DATETIME] NOT NULL,
    [ProcessThreadId] INT NULL
);

CREATE CLUSTERED INDEX [Cdx] ON [Table] 
(
    [DataType],
    [DataStatus],
    [ProcessDate]
);
/**************************************/

declare @BatchSize int, @ProcessThreadId int;

/**************************************/
WITH cte AS (
    SELECT TOP (@BatchSize) [PrimaryKeyId], [ProcessThreadId] , ... more columns 
    FROM [Table] WITH ( ROWLOCK, UPDLOCK, READPAST )
    WHERE [DataType] = 'X'
    AND [DataStatus] IS NULL
    AND [ProcessDate] < DATEADD(m, -2, GETDATE()) -- older than 2 months
    AND [ProcessThreadId] IS NULL
)
UPDATE cte
SET [ProcessThreadId] = @ProcessThreadId
OUTPUT DELETED.[PrimaryKeyId] , ... more columns ;
/**************************************/

এছাড়াও আমি সফলভাবে প্রক্রিয়াজাত আইটেমগুলিকে আলাদা, সংরক্ষণাগার, টেবিলের মধ্যে সরিয়ে নিয়ে যেতে বিবেচনা করব। আপনি চান যে আপনার সারি টেবিলগুলি শূন্য আকারের কাছাকাছি ঘুরে বেড়াতে চান, আপনি অনিবন্ধিত পুরানো এন্ট্রিগুলি থেকে 'ইতিহাস' বজায় রাখার কারণে সেগুলি বৃদ্ধি পেতে চান না। আপনি [ProcessDate]বিকল্প হিসাবে পার্টিশন বিবেচনা করতে পারেন (যেমন একটি বর্তমান সক্রিয় পার্টিশন যা সারি হিসাবে কাজ করে এবং NULL প্রসেসডেটের সাথে এন্ট্রি সঞ্চয় করে, এবং নন-নাল সব কিছুর জন্য অন্য একটি পার্টিশন। বাধ্যতামূলক সংরক্ষণের সময়টি পেরিয়ে গেছে এমন ডেটার জন্য মুছে ফেলুন (স্যুইচ আউট) things[DataType] যদি এটির পর্যাপ্ত নির্বাচনযোগ্যতা থাকে তবে সেই নকশাটি সত্যই জটিল হবে কারণ এটির জন্য অবিচ্ছিন্ন গণিত কলাম (একটি যৌগিক কলাম যা একসাথে [ডেটাটাইপ] এবং [প্রসেসিং ডেট]) বিভাজন প্রয়োজন।


3

আমি সরিয়ে শুরু করবেন ProcessDateএবং Processthreadidঅন্য টেবিলে ক্ষেত্র।

এই মুহুর্তে, এই প্রশস্ত প্রশস্ত সূচী থেকে আপনি নির্বাচন করা প্রতিটি সারিও আপডেট হওয়া দরকার।

যদি আপনি এই দুটি ক্ষেত্রকে অন্য টেবিলের দিকে নিয়ে যান তবে প্রধান টেবিলের উপর আপনার আপডেটের পরিমাণ 90% কেটে যাবে, যা বেশিরভাগ খণ্ডকে যত্ন নেওয়া উচিত।

আপনার কাছে এখনও নতুন টেবিলের টুকরো টুকরো থাকবে তবে সংক্ষিপ্ত টেবিলে অনেক কম ডেটা সহ পরিচালনা করা সহজ হবে।


এটি এবং শারীরিকভাবে [ডেটা টাইপ] এর উপর ভিত্তি করে ডেটা বিভক্ত করা আমার যেখানে হওয়া উচিত তা পাওয়া উচিত। আমি বর্তমানে এটির নকশা (পুনরায় নকশা করা) পর্যায়ে আছি তাই এই পরিবর্তনটি ড্রাইভ পরীক্ষা করার সুযোগ পাওয়ার আগে আমার কিছুটা সময় আসবে।
ক্রিস গ্যালুচি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.