প্রশ্নের চ্যালেঞ্জ: সারি গণনার নয় এমন একটি পরিমাপের ভিত্তিতে এমনকি আকারের বালতি তৈরি করা


12

আমি যথাসম্ভব সমানভাবে অর্ডার সহ একটি নির্দিষ্ট সংখ্যক ট্রাক লোড করার ক্ষেত্রে সমস্যাটি বর্ণনা করব।

ইনপুট:

@TruckCount - the number of empty trucks to fill

একটি সেট:

OrderId, 
OrderDetailId, 
OrderDetailSize, 
TruckId (initially null)

Ordersএক বা একাধিক নিয়ে গঠিত OrderDetails

এখানে চ্যালেঞ্জটি TruckIdপ্রতিটি রেকর্ডে একটি বরাদ্দ করা ।

একটি একক অর্ডার ট্রাকে বিভক্ত করা যায় না।

ট্রাকগুলি যথাসম্ভব সমান * লোড হওয়া উচিত, দ্বারা পরিমাপ করা উচিত sum(OrderDetailSize)

* সমান: সর্বনিম্ন বোঝা ট্রাক এবং সর্বাধিক বোঝা ট্রাকের মধ্যে ক্ষুদ্রতম অর্জনযোগ্য ব-দ্বীপ। এই সংজ্ঞা দ্বারা, 1,2,3 1,1,4 এর চেয়ে সমানভাবে বিতরণ করা হয়েছে। যদি এটি সহায়তা করে, আপনি স্ট্যাটস অ্যালগরিদম হিসাবে ভান করুন, এমনকি উচ্চতা হিস্টোগ্রাম তৈরি করে।

সর্বাধিক ট্রাক বোঝা বিবেচনা করা হয় না। এগুলি ম্যাজিক ইলাস্টিক ট্রাক। তবে ট্রাকের সংখ্যা নির্ধারিত।

একটি স্পষ্টত সমাধান আছে যা পুনরাবৃত্ত - গোলাকার রবিন আদেশ বরাদ্দ।

কিন্তু সেট সেট লজিক হিসাবে এটি করা যেতে পারে?

আমার মূল আগ্রহটি এসকিউএল সার্ভার ২০১৪ বা তারপরের জন্য। তবে অন্যান্য প্ল্যাটফর্মগুলির জন্য সেট ভিত্তিক সমাধানগুলি আকর্ষণীয়ও হতে পারে।

এটি ইতজিক বেন-গ্যান অঞ্চলটির মতো অনুভব করে :)

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

CREATE TABLE #OrderDetail (
OrderId int NOT NULL,
OrderDetailId int NOT NULL PRIMARY KEY,
OrderDetailSize tinyint NOT NULL,
TruckId tinyint NULL)

-- Sample Data

INSERT #OrderDetail (OrderId, OrderDetailId, OrderDetailSize)
VALUES
(1  ,100    ,75 ),
(2  ,101    ,5  ),
(2  ,102    ,5  ),
(2  ,103    ,5  ),
(2  ,104    ,5  ),
(2  ,105    ,5  ),
(3  ,106    ,100),
(4  ,107    ,1  ),
(5  ,108    ,11 ),
(6  ,109    ,21 ),
(7  ,110    ,49 ),
(8  ,111    ,25 ),
(8  ,112    ,25 ),
(9  ,113    ,40 ),
(10 ,114    ,49 ),
(11 ,115    ,10 ),
(11 ,116    ,10 ),
(12 ,117    ,15 ),
(13 ,118    ,18 ),
(14 ,119    ,26 )
--> YOUR SOLUTION HERE

-- After assigning Trucks, Measure delta between most and least loaded trucks.
-- Zero is perfect score, however the challenge is a set based solution that will scale, and produce good results, rather
-- than iterative solution that will produce perfect results by exploring every possibility.

SELECT max(TruckOrderDetailSize) - MIN(TruckOrderDetailSize) AS TruckMinMaxDelta
FROM 
(SELECT SUM(OrderDetailSize) AS TruckOrderDetailSize FROM #OrderDetail GROUP BY TruckId) AS Truck


DROP TABLE #OrderDetail

7
এটি ক্লাসিক বিন প্যাকিংয়ের সমস্যা বলে মনে হচ্ছে ।
ড্যান গুজম্যান


সমস্ত অর্ডারডেটল সাইজের মানগুলি কোনও প্রদত্ত অর্ডারআইডির জন্য সমান হবে বা এটি আপনার নমুনা ডেটাতে কেবল সহ-ঘটনা?
youcantryreachingme

@ ইয়ুক্যান্ট্রিরিচিংমে আহ, ভাল স্পট ... এটি স্যাম্পল ডেটাতে সহ-ঘটনা নয়।
পল হোমস

উত্তর:


5

আমার প্রথম চিন্তা ছিল

select
    <best solution>
from
    <all possible combinations>

"সেরা সমাধান" অংশটি প্রশ্নের মধ্যে সংজ্ঞায়িত করা হয় - সর্বাধিক বোঝা এবং সর্বনিম্ন বোঝা ট্রাকগুলির মধ্যে ক্ষুদ্রতম পার্থক্য। অন্য বিট - সমস্ত সংমিশ্রণ - আমাকে চিন্তার জন্য বিরতি দিয়েছে।

এমন একটি পরিস্থিতি বিবেচনা করুন যেখানে আমাদের কাছে তিনটি অর্ডার এ, বি এবং সি এবং তিনটি ট্রাক রয়েছে। সম্ভাবনা আছে

Truck 1 Truck 2 Truck 3
------- ------- -------
A       B       C
A       C       B
B       A       C
B       C       A
C       A       B
C       B       A
AB      C       -
AB      -       C
C       AB      -
-       AB      C
C       -       AB
-       C       AB
AC      B       -
AC      -       B
B       AC      -
-       AC      B
B       -       AC
-       B       AC
BC      A       -
BC      -       A
A       BC      -
-       BC      A
A       -       BC
-       A       BC
ABC     -       -
-       ABC     -
-       -       ABC

Table A: all permutations.

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

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

স্ট্যান্ডার্ড "সমস্ত সংমিশ্রণ" ক্যোয়ারী থেকে আউটপুটটি দেখছেন

;with Numbers as
(
    select n = 1
    union
    select 2
    union
    select 3
)
select
    a.n,
    b.n,
    c.n
from Numbers as a
cross join Numbers as b
cross join Numbers as c
order by 1, 2, 3;


  n   n   n
--- --- ---
  1   1   1
  1   1   2
  1   1   3
  1   2   1
 <snip>
  3   2   3
  3   3   1
  3   3   2
  3   3   3

Table B: cross join of three values.

আমি লক্ষনীয় ফলাফল সারণি উ হিসাবে একই প্যাটার্ন গঠিত প্রতিটি বিবেচনা congnitive লিপ করা হলে কলাম অর্ডার হতে 1 , মান বলতে যা ট্রাক রাখা করবে অর্ডার, এবং একটি সারি ট্রাক মধ্যে অর্ডারের ব্যবস্থা করতে হবে। কোয়েরিটি তখন হয়ে যায়

select
    Arrangement             = ROW_NUMBER() over(order by (select null)),
    First_order_goes_in     = a.TruckNumber,
    Second_order_goes_in    = b.TruckNumber,
    Third_order_goes_in     = c.TruckNumber
from Trucks a   -- aka Numbers in Table B
cross join Trucks b
cross join Trucks c

Arrangement First_order_goes_in Second_order_goes_in Third_order_goes_in
----------- ------------------- -------------------- -------------------
          1                   1                    1                   1
          2                   1                    1                   2
          3                   1                    1                   3
          4                   1                    2                   1
  <snip>

Query C: Orders in trucks.

উদাহরণস্বরূপ ডেটাতে চৌদ্দটি অর্ডার কভার করার জন্য এটি প্রসারিত করা এবং আমরা নামগুলি সহজ করে যাচ্ছি:

;with Trucks as
(
    select * 
    from (values (1), (2), (3)) as T(TruckNumber)
)
select
    arrangement = ROW_NUMBER() over(order by (select null)),
    First       = a.TruckNumber,
    Second      = b.TruckNumber,
    Third       = c.TruckNumber,
    Fourth      = d.TruckNumber,
    Fifth       = e.TruckNumber,
    Sixth       = f.TruckNumber,
    Seventh     = g.TruckNumber,
    Eigth       = h.TruckNumber,
    Ninth       = i.TruckNumber,
    Tenth       = j.TruckNumber,
    Eleventh    = k.TruckNumber,
    Twelth      = l.TruckNumber,
    Thirteenth  = m.TruckNumber,
    Fourteenth  = n.TruckNumber
into #Arrangements
from Trucks a
cross join Trucks b
cross join Trucks c
cross join Trucks d
cross join Trucks e
cross join Trucks f
cross join Trucks g
cross join Trucks h
cross join Trucks i
cross join Trucks j
cross join Trucks k
cross join Trucks l
cross join Trucks m
cross join Trucks n;

Query D: Orders spread over trucks.

আমি সুবিধার জন্য অস্থায়ী সারণিতে মধ্যবর্তী ফলাফল রাখা পছন্দ করি।

যদি ডেটা প্রথমে UNPIVOTED হয় তবে পরবর্তী পদক্ষেপগুলি আরও সহজ হবে।

select
    Arrangement,
    TruckNumber,
    ItemNumber  = case NewColumn
                    when 'First'        then 1
                    when 'Second'       then 2
                    when 'Third'        then 3
                    when 'Fourth'       then 4
                    when 'Fifth'        then 5
                    when 'Sixth'        then 6
                    when 'Seventh'      then 7
                    when 'Eigth'        then 8
                    when 'Ninth'        then 9
                    when 'Tenth'        then 10
                    when 'Eleventh'     then 11
                    when 'Twelth'       then 12
                    when 'Thirteenth'   then 13
                    when 'Fourteenth'   then 14
                    else -1
                end
into #FilledTrucks
from #Arrangements
unpivot
(
    TruckNumber
    for NewColumn IN 
    (
        First,
        Second,
        Third,
        Fourth,
        Fifth,
        Sixth,
        Seventh,
        Eigth,
        Ninth,
        Tenth,
        Eleventh,
        Twelth,
        Thirteenth,
        Fourteenth
    )
) as q;

Query E: Filled trucks, unpivoted.

অর্ডার সারণীতে যোগদানের মাধ্যমে ওজন প্রবর্তন করা যেতে পারে।

select
    ft.arrangement,
    ft.TruckNumber,
    TruckWeight = sum(i.Size)
into #TruckWeights
from #FilledTrucks as ft
inner join #Order as i
    on i.OrderId = ft.ItemNumber
group by
    ft.arrangement,
    ft.TruckNumber;

Query F: truck weights

সর্বাধিক-বোঝা এবং সর্বনিম্ন-বোঝা ট্রাকের মধ্যে সবচেয়ে কম পার্থক্য রয়েছে এমন ব্যবস্থা (গুলি) সন্ধানের মাধ্যমে প্রশ্নের উত্তর এখন দেওয়া যেতে পারে

select
    Arrangement,
    LightestTruck   = MIN(TruckWeight),
    HeaviestTruck   = MAX(TruckWeight),
    Delta           = MAX(TruckWeight) - MIN(TruckWeight)
from #TruckWeights
group by
    arrangement
order by
    4 ASC;

Query G: most balanced arrangements

আলোচনা

এটি দিয়ে একটি দুর্দান্ত অনেক সমস্যা রয়েছে। প্রথমত এটি একটি নিষ্ঠুর শক্তি অ্যালগরিদম। ওয়ার্কিং টেবিলগুলিতে সারিগুলির সংখ্যা ট্রাক এবং অর্ডার সংখ্যায় তাত্পর্যপূর্ণ। # অ্যারেঞ্জমেন্টে সারি সংখ্যা (ট্রাকের সংখ্যা) trucks (অর্ডার সংখ্যা)। এটি ভাল স্কেল হবে না।

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

তৃতীয়টি হচ্ছে ব্যবস্থাগুলিতে অপ্রয়োজনীয়। এটি মধ্যবর্তী টেবিলগুলি প্রবাহিত করে রানটাইমকে ব্যাপকভাবে বৃদ্ধি করে।

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

উপরের দিকে এটি নেতিবাচক ওজনগুলি পরিচালনা করে, আপনার উদ্যোগটি কি কখনও ভরা হিলিয়াম বালুনগুলি শিপিং শুরু করা উচিত!

থটস

যদি ট্রাক ও অর্ডারগুলির তালিকা থেকে সরাসরি # ফিল্ডট্রাকসকে জনবহুল করার কোনও উপায় থাকে তবে আমি মনে করি যে এই উদ্বেগগুলির মধ্যে সবচেয়ে খারাপটি পরিচালনাযোগ্য হবে। দুঃখের সাথে আমার অব্যবস্থাপনা সেই বাধাটিতে হোঁচট খেয়েছে। আমার আশা যে ভবিষ্যতের কিছু অবদানকারী আমাকে সরবরাহ করতে সক্ষম হতে পারে।




1 আপনি বলছেন যে কোনও অর্ডারের জন্য সমস্ত আইটেম একই ট্রাকে থাকতে হবে। এর অর্থ অ্যাসাইনমেন্টের পরমাণু হ'ল অর্ডার, অর্ডারডেটেল নয়। আমি আপনার পরীক্ষার ডেটা থেকে এইগুলি উত্পন্ন করেছি:

select
    OrderId,
    Size = sum(OrderDetailSize)
into #Order
from #OrderDetail
group by OrderId;

যদিও এতে আমরা 'অর্ডার' বা 'অর্ডারডেটেল' প্রশ্নে আইটেমগুলি লেবেল দিই না কেন, কোনও পার্থক্য নেই the


4

আপনার আসল বিশ্বের প্রয়োজনীয়তার দিকে তাকানো (যা আমি ধরে নিচ্ছি যে সিপাসের একটি সেট জুড়ে আপনার কাজের চাপ ভারসাম্য বজায় রাখার প্রয়াস চলছে) ...

নির্দিষ্ট বালতি / সিপাসে আপনাকে প্রসেস-পূর্ব নির্ধারিত করার কোনও কারণ আছে কি? [আপনার আসল প্রয়োজনীয়তা বোঝার চেষ্টা করছেন ]

আপনার 'পরিসংখ্যান আপডেটের' উদাহরণের জন্য, আপনি কীভাবে জানবেন যে কোনও নির্দিষ্ট ক্রিয়াকলাপ কতটা সময় নেবে? যদি কোনও প্রদত্ত ক্রিয়াকলাপটি অপ্রত্যাশিত বিলম্বের মধ্যে চলে যায় (যেমন, সারণী / সূচকের চেয়ে পরিকল্পনার চেয়ে বেশি / অত্যধিক খণ্ড বিভাজন, দীর্ঘ-চলমান ব্যবহারকারী টিএক্সএন 'স্ট্যাটাস আপডেট' অপারেশনটিকে অবরুদ্ধ করে)?


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

আপনার প্রয়োজনীয়তা অনুসারে সারণির কাঠামো পরিবর্তন করা যেতে পারে, যেমন:

create table tasks
(id        int             -- auto-increment?

,target    varchar(1000)   -- 'schema.table' to have stats updated, or perhaps ...
,command   varchar(1000)   -- actual command to be run, eg, 'update stats schema.table ... <options>'

,priority  int             -- provide means of ordering operations, eg, maybe you know some tasks will run really long so you want to kick them off first
,thread    int             -- identifier for parent process?
,start     datetime        -- default to NULL
,end       datetime        -- default to NULL
)

পরবর্তী আমি প্রতিটি প্রক্রিয়া নিম্নলিখিত সম্পাদন করে প্রকৃত 'পরিসংখ্যান আপডেট' ক্রিয়াকলাপ সম্পাদনের জন্য এক্স সংখ্যা সহকারী প্রক্রিয়াগুলি বন্ধ করে দিই:

  • tasksটেবিলের উপর একচেটিয়া লক রাখুন (একাধিক প্রক্রিয়া দ্বারা কোনও কাজ বাছাই করা নিশ্চিত করে না; তুলনামূলকভাবে স্বল্প-জীবনী লক হওয়া উচিত)
  • 'প্রথম' সারিটি সন্ধান করুন যেখানে start = NULL('প্রথম' আপনার দ্বারা নির্ধারিত হবে, উদাহরণস্বরূপ, আদেশ করুন priority?)
  • আপডেট সারি সেট start = getdate(), thread = <process_number>
  • কমিট আপডেট (এবং একচেটিয়া লক প্রকাশ)
  • idএবং target/commandমানগুলি নোট করুন
  • এর বিরুদ্ধে কাঙ্ক্ষিত অপারেশন করুন target(একযোগে চালান, চালান command) এবং হয়ে গেলে ...
  • আপডেটের tasksসঙ্গেend = getdate() where id = <id>
  • আর কোনও কাজ সম্পাদন না করা পর্যন্ত উপরে পুনরাবৃত্তি করুন

উপরের নকশার সাহায্যে আমি এখন একটি গতিশীল (বেশিরভাগ) সুষম অপারেশন পেয়েছি।

মন্তব্য:

  • আমি কিছু ধরণের অগ্রাধিকার পদ্ধতি সরবরাহ করার চেষ্টা করি যাতে আমি দীর্ঘকালীন চলমান কার্যগুলি সামনে থেকে সরিয়ে দিতে পারি; যখন বেশ কয়েকটি প্রক্রিয়া দীর্ঘতর চলমান কার্যগুলিতে কাজ করছে, অন্য প্রক্রিয়াগুলি ছোট কাজগুলির তালিকার মাধ্যমে মন্থন করতে পারে
  • যদি কোনও প্রক্রিয়া অপরিকল্পিত বিলম্বের মধ্যে চলে (যেমন, দীর্ঘকালীন, ব্যবহারকারী TXN ব্লক করা), অন্য প্রক্রিয়াগুলি 'পরবর্তী উপলব্ধ' অপারেশনটি এখান থেকে টানতে অবিরত করে 'স্ল্যাকটি তুলতে পারে' can tasks
  • tasksসারণির নকশায় অন্যান্য সুবিধাগুলির জন্য সরবরাহ করা উচিত, যেমন, আপনি ভবিষ্যতের রেফারেন্সের জন্য সংরক্ষণাগার রাখতে পারেন এমন রানের সময়ের ইতিহাস, অগ্রাধিকারগুলি সংশোধন করতে, বর্তমান ক্রিয়াকলাপের স্থিতি প্রদান ইত্যাদির ইতিহাস ইত্যাদির ইতিহাস etc
  • যদিও 'এক্সক্লুসিভ লক'টি tasksকিছুটা অতিরিক্ত মনে হতে পারে তবে মনে রাখবেন যে একই সময়ে সঠিক সময়ে একটি নতুন টাস্ক গ্রহণের চেষ্টা করার জন্য আমাদের 2 (বা আরও) প্রক্রিয়াগুলির সম্ভাব্য ইস্যুটির জন্য পরিকল্পনা করতে হবে , সুতরাং আমাদের কোনও কাজের গ্যারান্টি দেওয়া দরকার কেবলমাত্র একটি প্রক্রিয়াতে বরাদ্দ করা হয়েছে (এবং হ্যাঁ, আপনি কম্বো 'আপডেট / নির্বাচন করুন' বিবৃতি দিয়ে একই ফলাফলগুলি অর্জন করতে পারবেন - আপনার আরডিবিএমএসের এসকিউএল ভাষার দক্ষতার উপর নির্ভর করে); একটি নতুন 'টাস্ক' প্রাপ্তির পদক্ষেপটি দ্রুত হওয়া উচিত, অর্থাত্ 'এক্সক্লুসিভ লক' স্বল্পস্থায়ী হওয়া উচিত এবং বাস্তবে, প্রক্রিয়াগুলি tasksমোটামুটি এলোমেলো ফ্যাশনে আঘাত হানাবে তাই যাইহোক সামান্য অবরুদ্ধ হবে will

ব্যক্তিগতভাবে, আমি এই tasksটেবিল চালিত প্রক্রিয়াটিকে বাস্তবায়ন এবং বজায় রাখতে কিছুটা সহজ মনে করি ... কার্য (প্রসেস ম্যাপিং) -কে পূর্ব-নির্ধারিত করার আরও জটিল প্রক্রিয়াটির বিপরীতে ... ymmv।


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

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

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


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

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

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

1

আপনার ইচ্ছানুসারে নম্বর সারণী তৈরি এবং পপুলেট করুন his এটি কেবলমাত্র এক সময়ের সৃষ্টি।

 create table tblnumber(number int not null)

    insert into tblnumber (number)
    select ROW_NUMBER()over(order by a.number) from master..spt_values a
    , master..spt_values b

    CREATE unique clustered index CI_num on tblnumber(number)

ট্রাকের টেবিল তৈরি করা হয়েছে

CREATE TABLE #PaulWhiteTruck (
Truckid int NOT NULL)

insert into #PaulWhiteTruck
values(113),(203),(303)

declare @PaulTruckCount int
Select @PaulTruckCount= count(*) from #PaulWhiteTruck

CREATE TABLE #OrderDetail (
id int identity(1,1),
OrderId int NOT NULL,
OrderDetailId int NOT NULL PRIMARY KEY,
OrderDetailSize int NOT NULL,
TruckId int NULL
)

INSERT
#OrderDetail (OrderId, OrderDetailId, OrderDetailSize)
VALUES
(
1 ,100 ,75 ),(2 ,101 ,5 ),
(2 ,102 ,5 ),(2 ,103 ,5 ),
(2 ,104 ,5 ),(2 ,105 ,5 ),
(3 ,106 ,100),(4 ,107 ,1 ),
(5 ,108 ,11 ),(6 ,109 ,21 ),
(7 ,110 ,49 ),(8 ,111 ,25 ),
(8 ,112 ,25 ),(9 ,113 ,40 ),
(10 ,114 ,49 ),(11 ,115 ,10 ),
(11 ,116 ,10 ),(12 ,117 ,15 ),
(13 ,118 ,18 ),(14 ,119 ,26 )

আমি একটি OrderSummaryটেবিল তৈরি করেছি

create table #orderSummary(id int identity(1,1),OrderId int ,TruckOrderSize int
,bit_value AS
CONVERT
(
integer,
POWER(2, id - 1)
)
PERSISTED UNIQUE CLUSTERED)
insert into #orderSummary
SELECT OrderId, SUM(OrderDetailSize) AS TruckOrderSize
FROM #OrderDetail GROUP BY OrderId

DECLARE @max integer =
POWER(2,
(
SELECT COUNT(*) FROM #orderSummary 
)
) - 1
declare @Delta int
select @Delta= max(TruckOrderSize)-min(TruckOrderSize)   from #orderSummary

দয়া করে আমার ডেল্টার মানটি পরীক্ষা করুন এবং এটি ভুল কিনা তা আমাকে জানান

;WITH cte 
     AS (SELECT n.number, 
                c.* 
         FROM   dbo.tblnumber AS N 
                CROSS apply (SELECT s.orderid, 
                                    s.truckordersize 
                             FROM   #ordersummary AS s 
                             WHERE  n.number & s.bit_value = s.bit_value) c 
         WHERE  N.number BETWEEN 1 AND @max), 
     cte1 
     AS (SELECT c.number, 
                Sum(truckordersize) SumSize 
         FROM   cte c 
         GROUP  BY c.number 
        --HAVING sum(TruckOrderSize) between(@Delta-25) and (@Delta+25) 
        ) 
SELECT c1.*, 
       c.orderid 
FROM   cte1 c1 
       INNER JOIN cte c 
               ON c1.number = c.number 
ORDER  BY sumsize 

DROP TABLE #orderdetail 

DROP TABLE #ordersummary 

DROP TABLE #paulwhitetruck 

আপনি সিটিই 1 এর ফলাফল যাচাই করতে পারেন, এটি সব সম্ভব আছে Permutation and Combination of order along with their size

যদি আমার দৃষ্টিভঙ্গি এখানে অবধি সঠিক হয় তবে আমার কারও সাহায্য দরকার।

মুলতুবি টাস্ক:

ফিল্টার এবং CTE13 অংশ ( Truck count) এর ফলাফল ভাগ করুন যেমন Orderidপ্রতিটি গ্রুপের মধ্যে অনন্য এবং প্রতিটি অংশ টি ruckOrderSizeডেল্টার কাছাকাছি।


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