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

প্রশ্নটি বলছে যে আমরা সেই মানটি ভাগ করে নেওয়া অন্য সারিগুলি খুঁজে পেতে গ্রুপকি বা রেকর্ডকে অনুসরণ করতে পারি। সুতরাং আমরা গ্রাফের উভয়কেই ভার্টেক্স হিসাবে বিবেচনা করতে পারি। প্রশ্নটি কীভাবে গ্রুপকিজে ১-৩ সমান সুপারগ্রুপকি রয়েছে তা ব্যাখ্যা করতে চলেছে। এটিকে পাতলা রেখার সাথে বাম দিকে ক্লাস্টার হিসাবে দেখা যেতে পারে। ছবিতে মূল তথ্য দ্বারা গঠিত দুটি আরও উপাদান (সুপারগ্রুপকি )ও দেখায়।
এসকিউএল সার্ভারের টি-এসকিউএল অন্তর্নির্মিত কিছু গ্রাফ প্রসেসিং ক্ষমতা রয়েছে। এই সময়ে এটি বেশ স্বল্প, তবে এই সমস্যার সাথে সহায়ক নয়। এসকিউএল সার্ভারে আর এবং পাইথন এবং তাদের কাছে উপলব্ধ প্যাকেজের সমৃদ্ধ ও শক্তিশালী স্যুটকে কল করার ক্ষমতাও রয়েছে। এর মধ্যে একটি হ'ল ইগ্রাফ । এটি "লক্ষ লক্ষ প্রান্ত এবং প্রান্ত ( লিঙ্ক ) সহ বৃহত্তর গ্রাফগুলির দ্রুত পরিচালনা করার জন্য লেখা হয়েছে" ।
আর এবং ইগ্রাফ ব্যবহার করে আমি স্থানীয় পরীক্ষা 1 এ 2 মিনিট 22 সেকেন্ডে এক মিলিয়ন সারি প্রসেস করতে সক্ষম হয়েছি । এটি বর্তমানের সেরা সমাধানের সাথে তুলনা করে:
Record Keys Paul White R
------------ ---------- --------
Per question 15ms ~220ms
100 80ms ~270ms
1,000 250ms 430ms
10,000 1.4s 1.7s
100,000 14s 14s
1M 2m29 2m22s
1M n/a 1m40 process only, no display
The first column is the number of distinct RecordKey values. The number of rows
in the table will be 8 x this number.
1 এম সারিগুলি প্রক্রিয়া করার সময়, 1m40s গ্রাফটি লোড ও প্রক্রিয়া করার জন্য এবং টেবিলটি আপডেট করার জন্য ব্যবহৃত হত। আউটপুট সহ একটি এসএমএস ফলাফলের টেবিলটি তৈরি করতে 42 এর প্রয়োজন ছিল।
টাস্ক ম্যানেজারের পর্যবেক্ষণে যখন 1 এম সারি প্রক্রিয়াজাত হয় তখন প্রায় 3 জিবি ওয়ার্কিং মেমরির প্রয়োজন হয়। পেজিং ছাড়াই এটি এই সিস্টেমে উপলব্ধ ছিল।
আমি ইয়ার্প্যাকবের পুনরাবৃত্ত সিটিই পদ্ধতির মূল্যায়ন নিশ্চিত করতে পারি। কয়েক শ রেকর্ড কী সহ এটি 100% সিপিইউ এবং সমস্ত উপলব্ধ র্যাম ব্যবহার করেছে। অবশেষে টেম্পিডবিটি ৮০ গিগাবাইটেরও বেশি বেড়ে যায় এবং এসপিআইডি ক্র্যাশ হয়।
আমি সুপারগ্রুপকি কলামের সাথে পলের টেবিলটি ব্যবহার করেছি যাতে সমাধানগুলির মধ্যে সুষ্ঠু তুলনা হয়।
কোনও কারণে আর পয়েন্টারিতে উচ্চারণে আপত্তি জানালেন। এটি একটি সরল "e" এ পরিবর্তন করে এটি চালানোর অনুমতি দেয়। যেহেতু সমস্যাটি জার্মানিতে নেই, ততক্ষণ আমি তদন্ত করিনি। আমি নিশ্চিত একটি সমাধান আছে।
কোডটি এখানে
-- This captures the output from R so the base table can be updated.
drop table if exists #Results;
create table #Results
(
Component int not NULL,
Vertex varchar(12) not NULL primary key
);
truncate table #Results; -- facilitates re-execution
declare @Start time = sysdatetimeoffset(); -- for a 'total elapsed' calculation.
insert #Results(Component, Vertex)
exec sp_execute_external_script
@language = N'R',
@input_data_1 = N'select GroupKey, RecordKey from dbo.Example',
@script = N'
library(igraph)
df.g <- graph.data.frame(d = InputDataSet, directed = FALSE)
cpts <- components(df.g, mode = c("weak"))
OutputDataSet <- data.frame(cpts$membership)
OutputDataSet$VertexName <- V(df.g)$name
';
-- Write SuperGroupKey to the base table, as other solutions do
update e
set
SupergroupKey = r.Component
from dbo.Example as e
inner join #Results as r
on r.Vertex = e.RecordKey;
-- Return all rows, as other solutions do
select
e.SupergroupKey,
e.GroupKey,
e.RecordKey
from dbo.Example as e;
-- Calculate the elapsed
declare @End time = sysdatetimeoffset();
select Elapse_ms = DATEDIFF(MILLISECOND, @Start, @End);
আর কোড এটি করে
@input_data_1 এসকিউএল সার্ভার কীভাবে কোনও টেবিল থেকে আর কোডে ডেটা স্থানান্তর করে এবং ইনপুটডেটা সেট নামে একটি আর ডেটাফ্রেমে অনুবাদ করে।
library(igraph) আর এক্স কার্যকরকরণ পরিবেশে লাইব্রেরি আমদানি করে।
df.g <- graph.data.frame(d = InputDataSet, directed = FALSE)একটি ইগ্রাফ অবজেক্টে ডেটা লোড করুন। এটি একটি অপরিবর্তিত গ্রাফ যেহেতু আমরা দল থেকে লিঙ্কগুলি রেকর্ড করতে বা গোষ্ঠীতে রেকর্ড করতে পারি। ইনপুটডেটসেটটি এসকিউএল সার্ভারের আর-তে প্রেরিত ডেটাসেটের ডিফল্ট নাম।
cpts <- components(df.g, mode = c("weak")) পৃথক উপ-গ্রাফগুলি (উপাদানগুলি) এবং অন্যান্য ব্যবস্থা গ্রহণের জন্য গ্রাফটি প্রক্রিয়া করুন।
OutputDataSet <- data.frame(cpts$membership)এসকিউএল সার্ভার আর থেকে ডেটা ফ্রেম ফিরে প্রত্যাশা করে Its এর ডিফল্ট নাম আউটপুটডেটা সেট। উপাদানগুলি "সদস্যতা" নামে একটি ভেক্টরে সংরক্ষণ করা হয়। এই বিবৃতিটি ভেক্টরকে একটি ডেটা ফ্রেমে অনুবাদ করে।
OutputDataSet$VertexName <- V(df.g)$nameভি () গ্রাফের উল্লম্ব একটি ভেক্টর - গ্রুপকি এবং রেকর্ডকিগুলির একটি তালিকা। এটি তাদের আউটপুট ডেটা ফ্রেমে অনুলিপি করে, ভার্টেক্সনাম নামে একটি নতুন কলাম তৈরি করে। সুপারগ্রুপকে আপডেট করার জন্য সোর্স টেবিলের সাথে মেলে এই কীটি।
আমি কোনও আর বিশেষজ্ঞ নই। সম্ভবত এটি অনুকূলিত হতে পারে।
পরীক্ষার ডেটা
ওপি'র ডেটা বৈধতার জন্য ব্যবহৃত হয়েছিল। স্কেল পরীক্ষার জন্য আমি নিম্নলিখিত স্ক্রিপ্টটি ব্যবহার করেছি।
drop table if exists Records;
drop table if exists Groups;
create table Groups(GroupKey int NOT NULL primary key);
create table Records(RecordKey varchar(12) NOT NULL primary key);
go
set nocount on;
-- Set @RecordCount to the number of distinct RecordKey values desired.
-- The number of rows in dbo.Example will be 8 * @RecordCount.
declare @RecordCount int = 1000000;
-- @Multiplier was determined by experiment.
-- It gives the OP's "8 RecordKeys per GroupKey and 4 GroupKeys per RecordKey"
-- and allows for clashes of the chosen random values.
declare @Multiplier numeric(4, 2) = 2.7;
-- The number of groups required to reproduce the OP's distribution.
declare @GroupCount int = FLOOR(@RecordCount * @Multiplier);
-- This is a poor man's numbers table.
insert Groups(GroupKey)
select top(@GroupCount)
ROW_NUMBER() over (order by (select NULL))
from sys.objects as a
cross join sys.objects as b
--cross join sys.objects as c -- include if needed
declare @c int = 0
while @c < @RecordCount
begin
-- Can't use a set-based method since RAND() gives the same value for all rows.
-- There are better ways to do this, but it works well enough.
-- RecordKeys will be 10 letters, a-z.
insert Records(RecordKey)
select
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND())) +
CHAR(97 + (26*RAND()));
set @c += 1;
end
-- Process each RecordKey in alphabetical order.
-- For each choose 8 GroupKeys to pair with it.
declare @RecordKey varchar(12) = '';
declare @Groups table (GroupKey int not null);
truncate table dbo.Example;
select top(1) @RecordKey = RecordKey
from Records
where RecordKey > @RecordKey
order by RecordKey;
while @@ROWCOUNT > 0
begin
print @Recordkey;
delete @Groups;
insert @Groups(GroupKey)
select distinct C
from
(
-- Hard-code * from OP's statistics
select FLOOR(RAND() * @GroupCount)
union all
select FLOOR(RAND() * @GroupCount)
union all
select FLOOR(RAND() * @GroupCount)
union all
select FLOOR(RAND() * @GroupCount)
union all
select FLOOR(RAND() * @GroupCount)
union all
select FLOOR(RAND() * @GroupCount)
union all
select FLOOR(RAND() * @GroupCount)
union all
select FLOOR(RAND() * @GroupCount)
) as T(C);
insert dbo.Example(GroupKey, RecordKey)
select
GroupKey, @RecordKey
from @Groups;
select top(1) @RecordKey = RecordKey
from Records
where RecordKey > @RecordKey
order by RecordKey;
end
-- Rebuild the indexes to have a consistent environment
alter index iExample on dbo.Example rebuild partition = all
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF,
ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON);
-- Check what we ended up with:
select COUNT(*) from dbo.Example; -- Should be @RecordCount * 8
-- Often a little less due to random clashes
select
ByGroup = AVG(C)
from
(
select CONVERT(float, COUNT(1) over(partition by GroupKey))
from dbo.Example
) as T(C);
select
ByRecord = AVG(C)
from
(
select CONVERT(float, COUNT(1) over(partition by RecordKey))
from dbo.Example
) as T(C);
আমি এখনই বুঝতে পেরেছি যে আমি অনুপাতের সংজ্ঞাটি ওপি'র সংজ্ঞা থেকে ভুলভাবে পেয়েছি। আমি বিশ্বাস করি না এটি সময়ের সাথে প্রভাব ফেলবে। রেকর্ডস এবং গোষ্ঠীগুলি এই প্রক্রিয়াটির প্রতিসম হয়। অ্যালগরিদমের কাছে এগুলি সমস্ত গ্রাফের মধ্যে কেবল নোড।
তথ্য পরীক্ষায় অবিচ্ছিন্নভাবে একটি একক উপাদান তৈরি করা হয়। আমি বিশ্বাস করি এটি ডেটার অভিন্ন বিতরণের কারণে হয়েছে। স্থিতিশীল 1: 8 অনুপাতের পরিবর্তে প্রজন্মের রুটিনে হার্ড-কোডড আমি যদি অনুপাতটি পরিবর্তিত হওয়ার অনুমতি দিয়ে থাকি তবে সম্ভবত আরও উপাদান হতে পারে।
1 মেশিনের স্পেস: মাইক্রোসফ্ট এসকিউএল সার্ভার 2017 (আরটিএম-সিইউ 12), বিকাশকারী সংস্করণ (64-বিট), উইন্ডোজ 10 হোম। 16 জিবি র্যাম, এসএসডি, 4 কোর হাইপারথ্রেড আই 7, 2.8GHz নামমাত্র। সাধারণ সিস্টেম ক্রিয়াকলাপ (প্রায় 4% সিপিইউ) ব্যতীত পরীক্ষাগুলি কেবল তখনই চলত items