ব্যবহারকারী-সংজ্ঞায়িত স্ক্যালার ফাংশনটি এমনভাবে অনুকরণ করুন যা সমান্তরালতা প্রতিরোধ করে না


12

আমি চেষ্টা করছি যে এসকিউএল সার্ভারকে কোয়েরির জন্য একটি নির্দিষ্ট পরিকল্পনা ব্যবহার করার কৌশল আছে কিনা trick

1. পরিবেশ

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

if object_id('dbo.SharedData') is not null
    drop table SharedData

create table dbo.SharedData (
    experiment_year int,
    experiment_month int,
    rn int,
    calculated_number int,
    primary key (experiment_year, experiment_month, rn)
)
go

এখন, প্রতিটি প্রক্রিয়াটির জন্য আমাদের টেবিলে সংরক্ষণ করা প্যারামিটার রয়েছে

if object_id('dbo.Params') is not null
    drop table dbo.Params

create table dbo.Params (
    session_id int,
    experiment_year int,
    experiment_month int,
    primary key (session_id)
)
go

2. পরীক্ষার তথ্য

আসুন কিছু পরীক্ষার ডেটা যুক্ত করুন:

insert into dbo.Params (session_id, experiment_year, experiment_month)
select 1, 2014, 3 union all
select 2, 2014, 4 
go

insert into dbo.SharedData (experiment_year, experiment_month, rn, calculated_number)
select
    2014, 3, row_number() over(order by v1.name), abs(Checksum(newid())) % 10
from master.dbo.spt_values as v1
    cross join master.dbo.spt_values as v2
go

insert into dbo.SharedData (experiment_year, experiment_month, rn, calculated_number)
select
    2014, 4, row_number() over(order by v1.name), abs(Checksum(newid())) % 10
from master.dbo.spt_values as v1
    cross join master.dbo.spt_values as v2
go

৩. ফলাফল আনছে

এখন, এর দ্বারা পরীক্ষার ফলাফল পাওয়া খুব সহজ @experiment_year/@experiment_month:

create or alter function dbo.f_GetSharedData(@experiment_year int, @experiment_month int)
returns table
as
return (
    select
        d.rn,
        d.calculated_number
    from dbo.SharedData as d
    where
        d.experiment_year = @experiment_year and
        d.experiment_month = @experiment_month
)
go

পরিকল্পনাটি সুন্দর এবং সমান্তরাল:

select
    calculated_number,
    count(*)
from dbo.f_GetSharedData(2014, 4)
group by
    calculated_number

ক্যোয়ারী 0 পরিকল্পনা

এখানে চিত্র বর্ণনা লিখুন

4. সমস্যা

তবে, ডেটাটিকে কিছুটা জেনেরিক ব্যবহার করতে, আমি আরও একটি ফাংশন রাখতে চাই - dbo.f_GetSharedDataBySession(@session_id int)। সুতরাং, সহজবোধ্য উপায় স্কালে ফাংশন, অনুবাদ তৈরি করতে হবে @session_id-> @experiment_year/@experiment_month:

create or alter function dbo.fn_GetExperimentYear(@session_id int)
returns int
as
begin
    return (
        select
            p.experiment_year
        from dbo.Params as p
        where
            p.session_id = @session_id
    )
end
go

create or alter function dbo.fn_GetExperimentMonth(@session_id int)
returns int
as
begin
    return (
        select
            p.experiment_month
        from dbo.Params as p
        where
            p.session_id = @session_id
    )
end
go

এবং এখন আমরা আমাদের ফাংশন তৈরি করতে পারি:

create or alter function dbo.f_GetSharedDataBySession1(@session_id int)
returns table
as
return (
    select
        d.rn,
        d.calculated_number
    from dbo.f_GetSharedData(
        dbo.fn_GetExperimentYear(@session_id),
        dbo.fn_GetExperimentMonth(@session_id)
    ) as d
)
go

ক্যোয়ারী 1 পরিকল্পনা

এখানে চিত্র বর্ণনা লিখুন

অবশ্যই এটি সমান্তরাল নয়, ব্যতীত পরিকল্পনা একই, কারণ ডেটা অ্যাক্সেস সম্পাদনকারী স্কেলার ফাংশনগুলি পুরো পরিকল্পনাটিকে সিরিয়াল করে তোলে

সুতরাং আমি বিভিন্ন বিভিন্ন পদ্ধতির চেষ্টা করেছি, যেমন, স্কেলারের ফাংশনগুলির পরিবর্তে সাবকিউরিগুলি ব্যবহার করে:

create or alter function dbo.f_GetSharedDataBySession2(@session_id int)
returns table
as
return (
    select
        d.rn,
        d.calculated_number
    from dbo.f_GetSharedData(
       (select p.experiment_year from dbo.Params as p where p.session_id = @session_id),
       (select p.experiment_month from dbo.Params as p where p.session_id = @session_id)
    ) as d
)
go

ক্যোয়ারী 2 পরিকল্পনা

এখানে চিত্র বর্ণনা লিখুন

বা ব্যবহার cross apply

create or alter function dbo.f_GetSharedDataBySession3(@session_id int)
returns table
as
return (
    select
        d.rn,
        d.calculated_number
    from dbo.Params as p
        cross apply dbo.f_GetSharedData(
            p.experiment_year,
            p.experiment_month
        ) as d
    where
        p.session_id = @session_id
)
go

ক্যোয়ারী 3 পরিকল্পনা

এখানে চিত্র বর্ণনা লিখুন

তবে স্কেলার ফাংশনটি ব্যবহার করে যেমন করা যায় তেমন ভাল হওয়ার জন্য এই কোয়েরিটি লেখার কোনও উপায় আমি খুঁজে পাচ্ছি না।

দু'দিক চিন্তা:

  1. মূলত আমি যা চাই তা হ'ল কোনওভাবে এসকিউএল সার্ভারকে নির্দিষ্ট মানগুলি প্রাক-গণনা করতে এবং তারপরে ধ্রুবক হিসাবে আরও পাস করার জন্য সক্ষম হওয়া।
  2. সহায়ক কি হতে পারে যদি আমাদের কিছু মধ্যবর্তী বস্তুগতকরণের ইঙ্গিত থাকে। আমি বেশ কয়েকটি ভেরিয়েন্ট পরীক্ষা করেছি (মাল্টি-স্টেটমেন্ট টিভিএফ বা শীর্ষে সিটি), তবে এখন পর্যন্ত স্কেলার ফাংশনগুলির মতো কোনও পরিকল্পনা তেমন ভাল নয় no
  3. এসকিউএল সার্ভারের উন্নতি সম্পর্কে আমি জানি 2017 - ফায়ারয়েড: একটি সম্পর্কিত সম্পর্কিত ডেটাবেজে আবশ্যক প্রোগ্রামগুলির অনুকূলকরণ Iআমি নিশ্চিত নই যদিও এটি সাহায্য করবে। যদিও এখানে ভুল প্রমাণিত হয়ে ভাল লাগত।

অতিরিক্ত তথ্য

আমি একটি ফাংশন ব্যবহার করছি (টেবিলগুলি থেকে সরাসরি ডেটা নির্বাচন করার চেয়ে) কারণ অনেকগুলি বিভিন্ন ক্যোয়ারিতে এটি ব্যবহার করা অনেক সহজ, যা সাধারণত @session_idপ্যারামিটার হিসাবে থাকে ।

আমাকে প্রকৃত মৃত্যুদণ্ডের সময় তুলনা করতে বলা হয়েছিল। এই বিশেষ ক্ষেত্রে

  • ক্যোয়ারী 0 ~ 500ms এর জন্য চালায়
  • ক্যোয়ারী 1 runs 1500ms এর জন্য রান করে
  • ক্যোয়ারী 2 ~ 1500ms এর জন্য রান করে
  • ক্যোরি 3 2000 ডলারে চালায়।

প্ল্যান # 2 এর সন্ধানের পরিবর্তে একটি সূচক স্ক্যান রয়েছে, যা নেস্টেড লুপগুলিতে পূর্বাভাস দ্বারা ফিল্টার করা হয়। প্ল্যান # 3 এটি খারাপ নয়, তবে আরও বেশি কাজ করে এবং ধীর গতিতে কাজ করে যে পরিকল্পনা # 0।

ধরা যাক dbo.Paramsএটি খুব কমই পরিবর্তিত হয়েছে এবং সাধারণত প্রায় 1-200 সারি থাকে, এর চেয়ে বেশি নয়, ধরা যাক 2000 কখনও প্রত্যাশিত। এটি এখন প্রায় 10 টি কলাম এবং আমি প্রায়শই কলাম যুক্ত করার আশা করি না।

প্যারামগুলিতে সারিগুলির সংখ্যা নির্ধারিত নয়, সুতরাং প্রত্যেকের জন্য @session_idএকটি সারি থাকবে। সেখানে কলামগুলির সংখ্যা নির্ধারিত নয়, এটি আমি যে কোনও জায়গা থেকে কল করতে চাই না তার অন্যতম কারণ dbo.f_GetSharedData(@experiment_year int, @experiment_month int), তাই আমি অভ্যন্তরীণভাবে এই কোয়েরিতে নতুন কলাম যুক্ত করতে পারি। আমি এতে কোনও মতামত / পরামর্শ শুনে খুশি হব, এমনকি এতে কিছুটা বিধিনিষেধ রয়েছে।


Froid এর সাথে ক্যোয়ারী পরিকল্পনা উপরের ক্যোয়ার 2 এর সাথে একই রকম হবে, তাই হ্যাঁ, আপনি এই ক্ষেত্রে যে সমাধানটি পেতে চান তা আপনাকে গ্রহণ করবে না।
কার্তিক

উত্তর:


13

আপনি আজ এসকিউএল সার্ভারে যা চান ঠিক তা নিরাপদে অর্জন করতে পারবেন না, অর্থাত্ কোনও একক বিবৃতিতে এবং সমান্তরাল সম্পাদনের মাধ্যমে, প্রশ্নের মধ্যে বর্ণিত বিধিনিষেধের মধ্যে (যেমন আমি তাদের বুঝতে পেরেছি)।

সুতরাং আমার সহজ উত্তর না হয় । এই উত্তরটির বাকী অংশটি বেশিরভাগ ক্ষেত্রে কেন এটি আগ্রহী তা নিয়ে আলোচনা is

প্রশ্নে উল্লিখিত হিসাবে একটি সমান্তরাল পরিকল্পনা পাওয়া সম্ভব, তবে দুটি প্রধান প্রকারভেদ রয়েছে যা উভয়ই আপনার প্রয়োজনের জন্য উপযুক্ত নয়:

  1. শীর্ষ স্তরের রাউন্ড-রবিন বিতরণ স্ট্রিমের সাথে একটি সম্পর্কযুক্ত নেস্টেড লুপগুলি যোগ দেয়। একটি একক সারি Paramsএকটি নির্দিষ্ট session_idমান থেকে আসার নিশ্চয়তা দেওয়া হলেও, অভ্যন্তরীণ দিকটি একক থ্রেডে চলবে, যদিও এটি প্যারালালিজম আইকন দ্বারা চিহ্নিত থাকে। এ কারণেই আপাতদৃষ্টিতে সমান্তরাল পরিকল্পনা 3 পাশাপাশি সম্পাদন করে না; এটা আসলে সিরিয়াল।

  2. অন্য বিকল্প নেস্টেড লুপগুলি যোগ করার অভ্যন্তরের দিকে স্বাধীন সমান্তরালতার জন্য। ইন্ডিপেন্ডেন্টের অর্থ এখানে থ্রেডগুলি অভ্যন্তরীণ দিকে শুরু হয়েছিল, এবং কেবল একই থ্রেডগুলি নয় যা নেস্টেড লুপগুলির বাইরের দিকটি কার্যকর করছে join এসকিউএল সার্ভার কেবলমাত্র স্বতন্ত্র অভ্যন্তরীণ নেস্টযুক্ত লুপগুলি সমান্তরালতা সমর্থন করে যখন কোনও বাহ্যিক-সারি সারি হওয়ার গ্যারান্টিযুক্ত থাকে এবং কোনও সংযুক্ত জোড় প্যারামিটার থাকে না ( পরিকল্পনা 2 )।

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

তারপরে একটি প্রাকৃতিক প্রশ্ন হ'ল: আমাদের কেন একে অপরের সাথে সম্পর্কযুক্ত পরামিতিগুলির প্রয়োজন? এসকিউএল সার্ভার কেন সরাসরি উদাহরণস্বরূপ প্রদত্ত স্কেলারের মানগুলিতে সরাসরি অনুসন্ধান করতে পারে না?

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

সব মিলিয়ে, বর্তমানে ভেরিয়েবলগুলিতে লুক্কুচ মানগুলি নির্ধারণ এবং তারপরে ফাংশন পরামিতিগুলির পৃথক বিবৃতিতে ব্যবহারের মতো পদ্ধতির চেয়ে সত্যিকারের আর কোনও সমাধান নেই।

এখন আপনার নির্দিষ্ট স্থানীয় বিবেচনা হতে পারে যার অর্থ বছর এবং মাসের বর্তমান মানগুলি ক্যাশে SESSION_CONTEXTকরা উপযুক্ত অর্থাত্:

SELECT FGSD.calculated_number, COUNT_BIG(*)
FROM dbo.f_GetSharedData
(
    CONVERT(integer, SESSION_CONTEXT(N'experiment_year')), 
    CONVERT(integer, SESSION_CONTEXT(N'experiment_month'))
) AS FGSD
GROUP BY FGSD.calculated_number;

তবে এটি কাজের ভিত্তিতে চলে আসে।

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

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


ধন্যবাদ, পল, দুর্দান্ত উত্তর! আমি ব্যবহার সম্পর্কে ভেবেছিলাম session_contextতবে আমি সিদ্ধান্ত নিয়েছি যে এটি আমার জন্য একটি ধারণা কিছুটা পাগল এবং আমি কীভাবে এটি আমার বর্তমান স্থাপত্যের সাথে খাপ খায় তা নিশ্চিত নই। তবে কি কার্যকর হবে তা হ'ল, এমন কিছু ইঙ্গিত যা আমি অপ্টিমাইজারকে জানাতে ব্যবহার করতে পারি যে এটি একটি সাধারণ স্কেলার রেফারেন্সের মতো সাবকিউয়ের ফলাফলটিকে চিকিত্সা করা উচিত।
রোমান পেকার

8

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

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

সেগুলিই কেবলমাত্র সম্ভাব্য পরিকল্পনার আকার যা সম্পর্কে আমি অবগত। আপনি যদি কোনও টেম্প টেবিল ব্যবহার করেন তবে আপনি অন্য কাউকে পেতে পারেন তবে যদি আপনি কোয়েরি 0-এর জন্য কোয়েরি পারফরম্যান্সটি ঠিক তেমন ভাল হতে চান তবে সেগুলির কোনওটিই আপনার মৌলিক সমস্যার সমাধান করতে পারে না।

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

DECLARE @experiment_year int = dbo.fn_GetExperimentYear(@session_id);
DECLARE @experiment_month int = dbo.fn_GetExperimentMonth(@session_id);

select
    calculated_number,
    count(*)
from dbo.f_GetSharedData(@experiment_year, @experiment_month)
group by
    calculated_number;

আপনি যে সমান্তরালতার জন্য যোগ্য হতে চান সেই প্রশ্নের বাইরে স্কেলার ইউডিএফগুলি সরানো হয়েছে। আমি যে ক্যোয়ারী প্ল্যানটি পেয়েছি তা হ'ল আপনি যা চান তা হ'ল:

সমান্তরাল ক্যোয়ারী পরিকল্পনা

উভয় পদ্ধতিরই অসুবিধাগুলি রয়েছে যদি আপনার অন্যান্য প্রশ্নের মধ্যে এই ফলাফলটি সেট ব্যবহার করতে হয়। আপনি সরাসরি কোনও সঞ্চিত পদ্ধতিতে যোগদান করতে পারবেন না। আপনাকে ফলাফলগুলি একটি টেম্প টেবিলে সংরক্ষণ করতে হবে যার নিজস্ব সমস্যা রয়েছে। আপনি একটি এমএস-টিভিএফ-এ যোগ দিতে পারেন, তবে এসকিউএল সার্ভার ২০১ 2016-এ আপনি কার্ডিনালিটির প্রাক্কলন সম্পর্কিত সমস্যাগুলি দেখতে পাবেন। এসকিউএল সার্ভার 2017 এমএস-টিভিএফের জন্য আন্তঃবাহিত সম্পাদনের প্রস্তাব দেয় যা সমস্যাটি পুরোপুরি সমাধান করতে পারে।

কেবল কয়েকটি জিনিস সাফ করার জন্য: টি-এসকিউএল স্কেলার ইউডিএফ সর্বদা সমান্তরালতা নিষিদ্ধ করে এবং মাইক্রোসফ্ট বলেনি যে এসকিউএল সার্ভার 2017 এ ফ্রয়েড উপলব্ধ থাকবে।


এসকিউএল 2017 এ ফায়ারডের বিষয়ে - আমি কেন সেখানে ভেবেছিলাম তা নিশ্চিত নয়। এটি vNext- এ নিশ্চিত হয়েছে - brentozar.com/archive/2018/01/…
রোমান পেকার

4

এটি সম্ভবত এসকিউএলসিআরআর ব্যবহার করে করা যেতে পারে। SQLCLR স্কালে UDFs এক সুবিধা যে তারা উপমা প্রতিরোধ না যদি তারা না না কোন ডেটা অ্যাক্সেস না (এবং কখনও কখনও প্রয়োজন হিসাবে "নির্ণায়ক" হিসাবে চিহ্নিত করা)। অপারেশন নিজেই যখন ডেটা অ্যাক্সেসের প্রয়োজন হয় তখন আপনি কীভাবে এমন কোনও জিনিস ব্যবহার করবেন যাতে কোনও ডেটা অ্যাক্সেসের প্রয়োজন নেই?

ভাল, কারণ dbo.Paramsটেবিলটি প্রত্যাশিত:

  1. এটিতে সাধারণত 2000 সারি বেশি থাকে না,
  2. খুব কমই কাঠামো পরিবর্তন,
  3. শুধুমাত্র (বর্তমানে) দুটি INTকলাম থাকতে হবে

এটি তিনটি কলামকে ক্যাশে করা সম্ভব - session_id, experiment_year int, experiment_month- একটি স্ট্যাটিক সংগ্রহ (যেমন একটি অভিধান, সম্ভবত) যা প্রক্রিয়া বহির্ভূত হয় এবং স্কেলার ইউডিএফগুলি পড়ে experiment_year intএবং experiment_monthমানগুলি পায়। "প্রসেস-অফ-প্রসেস" দ্বারা আমি যা বোঝাতে চাইছি তা হল: আপনার কাছে একটি সম্পূর্ণ আলাদা এসকিউএলসিআরআর স্কেলার ইউডিএফ বা সঞ্চিত পদ্ধতি থাকতে পারে যা ডেটা অ্যাক্সেস করতে পারে এবং dbo.Paramsস্ট্যাটিক সংগ্রহটি জনপ্রিয় করতে টেবিল থেকে পড়তে পারে। "বছর" এবং "মাস" মান প্রাপ্ত UDF ব্যবহার করার আগে যে ইউডিএফ বা সঞ্চিত প্রক্রিয়া কার্যকর করা হত, সেইভাবে "বছর" এবং "মাস" মান প্রাপ্ত ইউডিএফ কোনও ডিবি ডেটা অ্যাক্সেস করে না।

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

মূল উদ্বেগ হ'ল এসকিউএল সার্ভার যখনই যে কোনও কারণে অ্যাপ ডোমেনটি আনলোড করার সিদ্ধান্ত নেয় (বা এটি ব্যবহার করে কোনও কিছু দ্বারা ট্রিগার হয় DBCC FREESYSTEMCACHE('ALL');)। "সংগ্রহ" ইউডিএফ বা সঞ্চিত পদ্ধতি এবং ইউডিএফগুলির "বর্ষ" এবং "মাস" মানগুলি অর্জনের মধ্যে যে সংগ্রহটি সাফ হয়ে গেছে তা আপনি ঝুঁকি নিতে চান না। এই ক্ষেত্রে সংগ্রহ দুটি খালি থাকলে ব্যতিক্রম ছুঁড়ে ফেলার জন্য এই দুটি ইউডিএফ-এর একেবারে শুরুতে আপনার একটি চেক থাকতে পারে, যেহেতু সাফল্যের সাথে মিথ্যা ফলাফল দেওয়ার চেয়ে ত্রুটি করা ভাল।

অবশ্যই, উপরে উল্লিখিত উদ্বেগ অনুমান করে যে সমাবেশটি হিসাবে চিহ্নিত হওয়ার ইচ্ছা রয়েছে SAFE। যদি অ্যাসেম্বলিটিকে চিহ্নিত করা যায় EXTERNAL_ACCESS, তবে কোনও স্ট্যাটিক কনস্ট্রাক্টর এমন পদ্ধতি প্রয়োগ করতে পারেন যা ডেটা পড়ে এবং সংগ্রহকে জনপ্রিয় করে তোলে, যাতে সারিগুলি রিফ্রেশ করার জন্য আপনাকে কেবল ম্যানুয়ালি কার্যকর করতে হবে তবে তারা সর্বদা পপুলেটে থাকবে (কারণ স্থির শ্রেণীর নির্মাতা যখন ক্লাস লোড হয় তখন সর্বদা চলতে থাকে, যখনই এই ক্লাসের কোনও পদ্ধতি পুনরায় আরম্ভের পরে বা অ্যাপ ডোমেনটি লোড না করে কার্যকর করা হয়) happens এটির জন্য নিয়মিত সংযোগ ব্যবহার করা প্রয়োজন এবং প্রক্রিয়াধীন প্রসঙ্গ সংযোগটি নয় (যা স্থির নির্মাতাদের কাছে উপলভ্য নয়, তাই এর প্রয়োজন EXTERNAL_ACCESS)।

দয়া করে নোট করুন: অ্যাসেম্বলি হিসাবে চিহ্নিত করার প্রয়োজন না হওয়ার জন্য আপনাকে যে UNSAFEকোনও স্থিতিশীল শ্রেণীর ভেরিয়েবল চিহ্নিত করতে হবে readonly। এর অর্থ হ'ল খুব কম সময়েই সংগ্রহ। এটি কোনও সমস্যা নয় যেহেতু কেবলমাত্র পঠনযোগ্য সংগ্রহগুলি তাদের থেকে আইটেম যুক্ত বা সরিয়ে ফেলতে পারে, কেবল সেগুলি নির্মাণকারী বা প্রাথমিক লোডের বাইরে আরম্ভ করা যায় না। সংগ্রহটি লোড হওয়ার সময়টি ট্র্যাক করে X মিনিটের পরে এটি মেয়াদ শেষ হওয়ার উদ্দেশ্যে কৌশলটি জটিল হয় কারণ একটি static readonly DateTimeবর্গ ভেরিয়েবল কনস্ট্রাক্টর বা প্রাথমিক লোডের বাইরে পরিবর্তন করা যায় না। এই সীমাবদ্ধতাটি পেতে, আপনাকে একটি স্ট্যাটিক, পঠনযোগ্য কেবল সংগ্রহ ব্যবহার করতে হবে যার মধ্যে একটি একক আইটেম রয়েছে DateTimeযাতে এটি মুছে ফেলা যায় এবং একটি রিফ্রেশের উপর পুনরায় যুক্ত করা যায়।


কেন কেউ এটিকে হ্রাস করেছে তা জানেন না। খুব জেনেরিক না হলেও, আমি মনে করি এটি আমার বর্তমান ক্ষেত্রে প্রযোজ্য হতে পারে। আমি খাঁটি এসকিউএল সমাধান পছন্দ করতে চাই, তবে আমি অবশ্যই এটিকে ঘনিষ্ঠভাবে পর্যবেক্ষণ করব এবং কাজ করে কিনা তা দেখার চেষ্টা করব
রোমান পেকার

@ রোমানপেকার নিশ্চিত নন, তবে সেখানে প্রচুর পরিমাণে লোক রয়েছে যা এসকিউএলসিএলবিরোধী। এবং সম্ভবত কয়েকটি যা আমার বিরোধী ;-)। যেভাবেই হোক, কেন এই সমাধানটি কার্যকর হবে না তা আমি ভাবতে পারি না। আমি খাঁটি টি-এসকিউএল এর পছন্দটি বুঝতে পারি, তবে কীভাবে তা ঘটানো যায় তা আমি জানি না এবং যদি কোনও প্রতিযোগিতামূলক উত্তর না থাকে, তবে অন্য কেউ হয় না maybe আমি জানি না মেমরিটি অনুকূলিত টেবিল এবং স্থানীয়ভাবে সংকলিত ইউডিএফগুলি এখানে আরও ভাল করতে পারে কিনা here এছাড়াও, আমি মনে রাখার জন্য কিছু বাস্তবায়ন নোট সহ একটি অনুচ্ছেদ যুক্ত করেছি।
সলোমন রুটজকি

1
readonly staticsএসকিউএলসিআরআর-তে ব্যবহার করা নিরাপদ বা বুদ্ধিমান বলে আমি কখনই পুরোপুরি নিশ্চিত হইনি। এরপরে আমি নিশ্চিত হয়েছি যে readonlyরেফারেন্স টাইপ করে সিস্টেমটিকে বোকা বানাতে যাচ্ছি , যা আপনি তারপর যান এবং পরিবর্তন করেন । আমাকে পরম ইচ্ছা টিবিএইচ দেয়।
পল হোয়াইট 9

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

2
দরকার নেই, অফিসিয়াল এসকিউএল সার্ভারের ডকুমেন্টেশনটি বাদ দিয়ে আপনি আমাকে এতে স্বাচ্ছন্দ্য বোধ করার উপায় নেই যে এটি ঠিক আছে, যা আমি নিশ্চিত যে এর অস্তিত্ব নেই।
পল হোয়াইট 9
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.