পুনরাবৃত্ত স্কয়ার ক্যোয়ারী কর্মক্ষমতা ইস্যু [বন্ধ]


9

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

বিমূর্ত

আমার একটি ডেটাবেস রয়েছে, এটি কান্ড অভিনব উপায়ে ডেটা সংরক্ষণের অনুমতি দেয় এবং আমার ব্যবসায়িক প্রক্রিয়া দ্বারা প্রয়োজনীয় বেশ কয়েকটি অ-মানক বৈশিষ্ট্য সরবরাহ করে। বৈশিষ্ট্যগুলি নিম্নলিখিত:

  1. অ-ধ্বংসাত্মক এবং অ-ব্লকিং আপডেট / মুছে ফেলা কেবলমাত্র সন্নিবেশের পদ্ধতির মাধ্যমে প্রয়োগ করা হয়, যা তথ্য পুনরুদ্ধার এবং স্বয়ংক্রিয় লগিংয়ের অনুমতি দেয় (প্রতিটি পরিবর্তন সেই ব্যবহারকারীকে আবদ্ধ করা হয় যারা এই পরিবর্তনটি করেছেন)
  2. মাল্টিভারসিওন ডেটা (একই ডেটার একাধিক সংস্করণ থাকতে পারে)
  3. ডাটাবেস-স্তর অনুমতি
  4. এসিডি স্পেসিফিকেশন এবং লেনদেন-নিরাপদ তৈরি / আপডেট / মুছে ফেলার সাথে পরিণামসই ধারাবাহিকতা
  5. আপনার বর্তমান তথ্যের দর্শনকে যে কোনও সময়ে সময়ে রিওয়াইন্ড বা দ্রুত-ফরওয়ার্ড করার ক্ষমতা।

অন্যান্য বৈশিষ্ট্য থাকতে পারে যা আমি উল্লেখ করতে ভুলে গেছি।

ডাটাবেস কাঠামো

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

ফলস্বরূপ উপাত্তগুলি পুরোভাগে লিঙ্কযুক্ত গ্রাফের সম্মুখভাগে লিঙ্কযুক্ত (জোইনড) হয় তাই বেশিরভাগ ক্ষেত্রে ডাটাবেস অনুসন্ধান করার প্রয়োজন নেই।

জসন এনকোডড ফর্মটি সংরক্ষণের পরিবর্তে নিয়মিত এসকিউএল কলামগুলিতে ডেটা সঞ্চয় করাও সম্ভব। তবে এটি সামগ্রিক জটিলতার স্ট্রেনকে বাড়িয়ে তোলে।

তথ্য পড়া

GetLatestনির্দেশাবলীর আকারে ডেটার সাথে ফলাফল, বিবেচনা নিম্নলিখিত ডায়াগ্রাম ব্যাখ্যা জন্য:

কাঠামোর চিত্র

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

সুতরাং GetLatestনিম্নলিখিত ইনপুট টাইমস্প্যানের মধ্যে কল করার ফলে নিম্নলিখিত রেকর্ড সংস্করণগুলি পাওয়া যাবে:

GetLatest 0, 15  => 1       <= The data is created upon it's first occurance
GetLatest 0, 25  => 2       <= Inserting another version on top of first one overwrites the existing version
GetLatest 0, 30  => 3       <= The overwrite takes place as soon as the data is inserted
GetLatest 0, 45  => 3, 4    <= This is where the conflict is introduced in the system
GetLatest 0, 55  => 4, 5    <= You can still edit all the versions
GetLatest 0, 65  => 4, 6    <= You can still edit all the versions
GetLatest 0, 75  => 4, 6, 7 <= You can also create additional conflicts
GetLatest 0, 85  => 4, 7, 8 <= You can still edit records
GetLatest 0, 95  => 7, 8, 9 <= You can still edit records
GetLatest 0, 105 => 7, 8    <= Inserting a record with `Json` equal to `NULL` means that the record is deleted
GetLatest 0, 115 => 8       <= Deleting the conflicting versions is the only conflict-resolution scenario
GetLatest 0, 125 => 8, X    <= The conflict can be based on the version that was already deleted.
GetLatest 0, 135 => 8, Y    <= You can delete such version too and both undelete another version on parallel within one Snapshot (or in several Snapshots).
GetLatest 0, 145 => 8       <= You can delete the undeleted versions by inserting NULL.
GetLatest 0, 155 => 8, Z    <= You can again undelete twice-deleted versions
GetLatest 0, 165 => 8       <= You can again delete three-times deleted versions
GetLatest 0, 10000 => 8     <= This means that in order to fast-forward view from moment 0 to moment `10000` you just have to expose record 8 to the user.
GetLatest 55, 115  => 8, [Remove 4], [Remove 5] <= At moment 55 there were two versions [4, 5] so in order to fast-forward to moment 115 the user has to delete versions 4 and 5 and introduce version 8. Please note that version 7 is not present in results since at moment 110 it got deleted.

আদেশের জন্য এ GetLatestধরনের দক্ষ ইন্টারফেস প্রতিটি রেকর্ডের বিশেষ সেবা বৈশিষ্ট্যাবলী থাকা উচিত সমর্থন করার জন্য BranchId, RecoveredOn, CreatedOn, UpdatedOnPrev, UpdatedOnCurr, UpdatedOnNext, UpdatedOnNextIdদ্বারা ব্যবহৃত হয় যে GetLatestকিনা রেকর্ডের জন্য উপলব্ধ timespan মধ্যে পর্যাপ্তরূপে পড়ে জিনিসটা GetLatestআর্গুমেন্ট

তথ্য .োকানো হচ্ছে

চূড়ান্ত ধারাবাহিকতা, লেনদেনের সুরক্ষা এবং কার্যকারিতা সমর্থন করার জন্য, বিশেষ মাল্টিস্টেজ পদ্ধতির মাধ্যমে ডেটাবেসে ডেটা dataোকানো হয়।

  1. GetLatestসঞ্চিত প্রক্রিয়া দ্বারা জিজ্ঞাসা করতে সক্ষম না হয়ে ডেটা কেবলমাত্র ডাটাবেসে প্রবেশ করানো হয়েছে ।

  2. GetLatestসঞ্চিত পদ্ধতির জন্য ডেটা উপলব্ধ করা হয় , তথ্যটি সাধারণীকরণ (যেমন denormalized = 0) অবস্থায় উপলব্ধ করা হয় । তথ্য সাধারণ অবস্থায় যদিও, সেবা ক্ষেত্র BranchId, RecoveredOn, CreatedOn, UpdatedOnPrev, UpdatedOnCurr, UpdatedOnNext, UpdatedOnNextIdনির্ণিত করা হচ্ছে যা সত্যিই ধীর।

  3. জিনিসগুলির গতি বাড়ানোর জন্য, GetLatestসঞ্চিত প্রক্রিয়াটির জন্য ডেটা উপলব্ধ হওয়ার সাথে সাথেই তা অস্বীকৃত করা হচ্ছে ।

    • বিভিন্ন লেনদেনের মধ্যে পরিচালিত 1,2,3 পদক্ষেপগুলি যেহেতু প্রতিটি অপারেশনের মাঝখানে কোনও হার্ডওয়্যার ব্যর্থতা দেখা দিতে পারে। মধ্যবর্তী অবস্থায় ডেটা রেখে দেওয়া এ জাতীয় পরিস্থিতি স্বাভাবিক এবং এটি ঘটতে থাকলেও নিম্নলিখিত InsertSnapshotকলের মধ্যে ডেটা নিরাময় হবে । এই অংশটির কোডটি InsertSnapshotসঞ্চিত পদ্ধতির 2 এবং 3 পদক্ষেপের মধ্যে খুঁজে পাওয়া যায় ।

সমস্যাটি

একটি নতুন বৈশিষ্ট্য (ব্যবসা প্রয়োজনীয়) আমার বিশেষ refactor করতে বাধ্য Denormalizerদৃশ্য যা বন্ধন-আপ সব একসাথে অতিরিক্ত বৈশিষ্ট্যগুলিও উপস্থিত রয়েছে এবং উভয় জন্য ব্যবহার করা হয় GetLatestএবং InsertSnapshot। এর পরে আমি পারফরম্যান্স সমস্যার সম্মুখীন হতে শুরু করেছি। যদি প্রাথমিকভাবে SELECT * FROM Denormalizerকেবল দ্বিতীয়টির ভগ্নাংশে কার্যকর করা হয় তবে এখন এটি 10000 রেকর্ড প্রক্রিয়া করতে প্রায় 5 মিনিট সময় নেয়।

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

ALTER VIEW [dbo].[Denormalizer]
AS
WITH Computed AS
(
    SELECT  currItem.Id,
            nextOperation.id AS NextId,
            prevOperation.FinishedOn AS PrevComputed,
            currOperation.FinishedOn AS CurrComputed,
            nextOperation.FinishedOn AS NextComputed

    FROM Items currItem 
    INNER JOIN dbo.Operations AS currOperation ON currItem.OperationId = currOperation.Id

    LEFT OUTER JOIN dbo.Items AS prevItem ON currItem.PreviousId = prevItem.Id
    LEFT OUTER JOIN dbo.Operations AS prevOperation ON prevItem.OperationId = prevOperation.Id 
    LEFT OUTER JOIN
    (
        SELECT MIN(I.id) as id, S.PreviousId, S.FinishedOn
        FROM Items I
        INNER JOIN
        (
            SELECT I.PreviousId, MIN(nxt.FinishedOn) AS FinishedOn
            FROM dbo.Items I
            LEFT OUTER JOIN dbo.Operations AS nxt ON I.OperationId = nxt.Id
            GROUP BY I.PreviousId
        ) AS S ON I.PreviousId = S.PreviousId 
        GROUP BY S.PreviousId, S.FinishedOn
    ) AS nextOperation ON nextOperation.PreviousId = currItem.Id

    WHERE currOperation.Finished = 1 AND currItem.Denormalized = 0
),

RecursionInitialization AS
(
    SELECT  currItem.Id,
            currItem.PreviousId,
            currItem.UUID,
            currItem.Json,
            currItem.TableName,
            currItem.OperationId,
            currItem.PermissionId,
            currItem.Denormalized,
            currItem.Id AS BranchID,
            COALESCE (C.PrevComputed, C.CurrComputed) AS CreatedOn,
            COALESCE (C.PrevComputed, CAST(0 AS BIGINT)) AS RecoveredOn,
            COALESCE (C.PrevComputed, CAST(0 AS BIGINT)) AS UpdatedOnPrev,
            C.CurrComputed AS UpdatedOnCurr,
            COALESCE (C.NextComputed, CAST(8640000000000000 AS BIGINT)) AS UpdatedOnNext,
            C.NextId AS UpdatedOnNextId,

            0 AS RecursionLevel

    FROM Items AS currItem
    INNER JOIN Computed AS C ON currItem.Id = C.Id
    WHERE currItem.Denormalized = 0

    UNION ALL

    SELECT  currItem.Id,
            currItem.PreviousId,
            currItem.UUID,
            currItem.Json,
            currItem.TableName,
            currItem.OperationId,
            currItem.PermissionId,
            currItem.Denormalized,
            currItem.BranchId,
            currItem.CreatedOn,
            currItem.RecoveredOn,
            currItem.UpdatedOnPrev,
            currItem.UpdatedOnCurr,
            currItem.UpdatedOnNext,
            currItem.UpdatedOnNextId,

            0 AS RecursionLevel

    FROM Items AS currItem
    WHERE currItem.Denormalized = 1
),
Recursion AS
(
    SELECT *
    FROM RecursionInitialization AS currItem

    UNION ALL

    SELECT  currItem.Id,
            currItem.PreviousId,
            currItem.UUID,
            currItem.Json,
            currItem.TableName,
            currItem.OperationId,
            currItem.PermissionId,
            currItem.Denormalized,

            CASE
                WHEN prevItem.UpdatedOnNextId = currItem.Id
                THEN prevItem.BranchID
                ELSE currItem.Id
            END AS BranchID,

            prevItem.CreatedOn AS CreatedOn,

            CASE
                WHEN prevItem.Json IS NULL
                THEN CASE
                            WHEN currItem.Json IS NULL
                            THEN prevItem.RecoveredOn
                            ELSE C.CurrComputed
                        END
                ELSE prevItem.RecoveredOn
            END AS RecoveredOn,

            prevItem.UpdatedOnCurr AS UpdatedOnPrev,

            C.CurrComputed AS UpdatedOnCurr,

            COALESCE (C.NextComputed, CAST(8640000000000000 AS BIGINT)) AS UpdatedOnNext,

            C.NextId,

            prevItem.RecursionLevel + 1 AS RecursionLevel
    FROM Items currItem
    INNER JOIN Computed C ON currItem.Id = C.Id
    INNER JOIN Recursion AS prevItem ON currItem.PreviousId = prevItem.Id
    WHERE currItem.Denormalized = 0
)
SELECT  item.Id,
        item.PreviousId,
        item.UUID,
        item.Json,
        item.TableName,
        item.OperationId,
        item.PermissionId,
        item.Denormalized,
        item.BranchID,
        item.CreatedOn,
        item.RecoveredOn,
        item.UpdatedOnPrev,
        item.UpdatedOnCurr,
        item.UpdatedOnNext,
        item.UpdatedOnNextId

FROM Recursion AS item
INNER JOIN
(
    SELECT Id, MAX(RecursionLevel) AS Recursion
    FROM Recursion AS item
    GROUP BY Id
) AS nested ON item.Id = nested.Id AND item.RecursionLevel = nested.Recursion
GO

প্রশ্নসমুহ)

দুটি পরিস্থিতি বিবেচনা করা হয়, অস্বীকৃত এবং স্বাভাবিকীকরণ ক্ষেত্রে:

  1. আসল ব্যাকআপের SELECT * FROM Denormalizerদিকে তাকানো , কী এতটা বেদনাদায়ক ধীর করে দেয়, আমার মনে হয় ডেনারমালাইজার ভিউয়ের পুনরাবৃত্ত অংশ নিয়ে কোনও সমস্যা আছে, আমি সীমাবদ্ধ করার চেষ্টা করেছি denormalized = 1তবে আমার ক্রিয়াকলাপের কোনও কারণে প্রভাবিত হয়নি।

  2. চালানোর পর UPDATE Items SET Denormalized = 0এটা করতে হবে GetLatestএবং SELECT * FROM Denormalizerমধ্যে চালানো ধীর দৃশ্যকল্প (মূলত বলে মনে করা), সেখানে গতি জিনিষ আপ আমরা পরিষেবাটি ক্ষেত্র কম্পিউটিং যখন একটি উপায় BranchId, RecoveredOn, CreatedOn, UpdatedOnPrev, UpdatedOnCurr, UpdatedOnNext,UpdatedOnNextId

তুমাকে অগ্রিম ধন্যবাদ

পুনশ্চ

ভবিষ্যতের জন্য মাইএসকিউএল / ওরাকল / এসকিউএল যেমন অন্য ডাটাবেসে ক্যোয়ারিকে সহজেই পোর্টেবল করার জন্য আমি স্ট্যান্ডার্ড এসকিউএলকে আঁকড়ে রাখার চেষ্টা করছি, তবে যদি এমন কোনও স্ট্যান্ডার্ড এসকিউএল না থাকে যা সাহায্য করতে পারে তবে আমি ডাটাবেস-নির্দিষ্ট কাঠামোয় লেগে থাকা ঠিক আছি।


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

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

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

উত্তর:


9

@ লু 4 .. আমি এই প্রশ্নটিকে "আইসবার্গের টিপ" হিসাবে বন্ধ করার পক্ষে ভোট দিয়েছি কিন্তু ক্যোয়ারির ইঙ্গিতটি ব্যবহার করে আপনি এটি 1 সেকেন্ডের অধীনে চালাতে সক্ষম হবেন। এই ক্যোয়ারীটি রিফ্যাক্টর করা যেতে পারে এবং ব্যবহার করতে পারে CROSS APPLYতবে এটি একটি পরামর্শ গিগ হবে এবং কোনও প্রশ্নোত্তর সাইটের উত্তর হিসাবে নয়।

আপনার ক্যোয়ারীটি 4+ সিপিইউ এবং 16 জিবি র‌্যাম সহ 13+ মিনিটের জন্য আমার সার্ভারে চলবে।

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

আমি আপনার জিজ্ঞাসাটি ব্যবহার করতে পরিবর্তন করেছি OPTION(MERGE JOIN)এবং এটি 1 সেকেন্ডের মধ্যে চলে

set nocount on 
set statistics io on
set statistics time on
;WITH Computed AS
(
    SELECT  currItem.Id,
            nextOperation.id AS NextId,
            prevOperation.FinishedOn AS PrevComputed,
            currOperation.FinishedOn AS CurrComputed,
            nextOperation.FinishedOn AS NextComputed

    FROM Items currItem 
    INNER JOIN dbo.Operations AS currOperation ON currItem.OperationId = currOperation.Id

    LEFT OUTER JOIN dbo.Items AS prevItem ON currItem.PreviousId = prevItem.Id
    LEFT OUTER JOIN dbo.Operations AS prevOperation ON prevItem.OperationId = prevOperation.Id 
    LEFT OUTER JOIN
    (
        SELECT MIN(I.id) as id, S.PreviousId, S.FinishedOn
        FROM Items I
        INNER JOIN
        (
            SELECT I.PreviousId, MIN(nxt.FinishedOn) AS FinishedOn
            FROM dbo.Items I
            LEFT OUTER JOIN dbo.Operations AS nxt ON I.OperationId = nxt.Id
            GROUP BY I.PreviousId
        ) AS S ON I.PreviousId = S.PreviousId 
        GROUP BY S.PreviousId, S.FinishedOn
    ) AS nextOperation ON nextOperation.PreviousId = currItem.Id

    WHERE currOperation.Finished = 1 AND currItem.Denormalized = 0
),

RecursionInitialization AS
(
    SELECT  currItem.Id,
            currItem.PreviousId,
            currItem.UUID,
            currItem.Json,
            currItem.TableName,
            currItem.OperationId,
            currItem.PermissionId,
            currItem.Denormalized,
            currItem.Id AS BranchID,
            COALESCE (C.PrevComputed, C.CurrComputed) AS CreatedOn,
            COALESCE (C.PrevComputed, CAST(0 AS BIGINT)) AS RecoveredOn,
            COALESCE (C.PrevComputed, CAST(0 AS BIGINT)) AS UpdatedOnPrev,
            C.CurrComputed AS UpdatedOnCurr,
            COALESCE (C.NextComputed, CAST(8640000000000000 AS BIGINT)) AS UpdatedOnNext,
            C.NextId AS UpdatedOnNextId,

            0 AS RecursionLevel

    FROM Items AS currItem
    INNER JOIN Computed AS C ON currItem.Id = C.Id
    WHERE currItem.Denormalized = 0

    UNION ALL

    SELECT  currItem.Id,
            currItem.PreviousId,
            currItem.UUID,
            currItem.Json,
            currItem.TableName,
            currItem.OperationId,
            currItem.PermissionId,
            currItem.Denormalized,
            currItem.BranchId,
            currItem.CreatedOn,
            currItem.RecoveredOn,
            currItem.UpdatedOnPrev,
            currItem.UpdatedOnCurr,
            currItem.UpdatedOnNext,
            currItem.UpdatedOnNextId,

            0 AS RecursionLevel

    FROM Items AS currItem
    WHERE currItem.Denormalized = 1
),
Recursion AS
(
    SELECT *
    FROM RecursionInitialization AS currItem

    UNION ALL

    SELECT  currItem.Id,
            currItem.PreviousId,
            currItem.UUID,
            currItem.Json,
            currItem.TableName,
            currItem.OperationId,
            currItem.PermissionId,
            currItem.Denormalized,

            CASE
                WHEN prevItem.UpdatedOnNextId = currItem.Id
                THEN prevItem.BranchID
                ELSE currItem.Id
            END AS BranchID,

            prevItem.CreatedOn AS CreatedOn,

            CASE
                WHEN prevItem.Json IS NULL
                THEN CASE
                            WHEN currItem.Json IS NULL
                            THEN prevItem.RecoveredOn
                            ELSE C.CurrComputed
                        END
                ELSE prevItem.RecoveredOn
            END AS RecoveredOn,

            prevItem.UpdatedOnCurr AS UpdatedOnPrev,

            C.CurrComputed AS UpdatedOnCurr,

            COALESCE (C.NextComputed, CAST(8640000000000000 AS BIGINT)) AS UpdatedOnNext,

            C.NextId,

            prevItem.RecursionLevel + 1 AS RecursionLevel
    FROM Items currItem
    INNER JOIN Computed C ON currItem.Id = C.Id
    INNER JOIN Recursion AS prevItem ON currItem.PreviousId = prevItem.Id
    WHERE currItem.Denormalized = 0
)
SELECT  item.Id,
        item.PreviousId,
        item.UUID,
        item.Json,
        item.TableName,
        item.OperationId,
        item.PermissionId,
        item.Denormalized,
        item.BranchID,
        item.CreatedOn,
        item.RecoveredOn,
        item.UpdatedOnPrev,
        item.UpdatedOnCurr,
        item.UpdatedOnNext,
        item.UpdatedOnNextId

FROM Recursion AS item
INNER JOIN
(
    SELECT Id, MAX(RecursionLevel) AS Recursion
    FROM Recursion AS item
    GROUP BY Id
) AS nested ON item.Id = nested.Id AND item.RecursionLevel = nested.Recursion
OPTION (MERGE JOIN)

set nocount oFF 
set statistics io OFF
set statistics time OFF

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

নোট করুন যে আপনি একটি ভিউতে ক্যোয়ারী ইঙ্গিতগুলি ব্যবহার করতে পারবেন না, তাই আপনাকে এসপি বা কোনও কর্মক্ষেত্র হিসাবে নিজের দৃষ্টিভঙ্গি তৈরি করার বিকল্পটি বের করতে হবে


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

@ লু 4 সমস্যাটি হ'ল ক্যোরি অপটিমাইজার সেরা নির্বাহী পরিকল্পনাটি বেছে নিচ্ছে না (বা জেনারেট করছে)। এই ক্ষেত্রে ক্যোয়ারী ইঙ্গিতটি অপ্টিমাইজারটিকে যোগদানটি বাস্তবায়নের জন্য একটি নির্দিষ্ট কৌশল ব্যবহার করতে 'উত্সাহ দেয়'। দেখুন সংকেতগুলি (লেনদেন এসকিউএল) যোগদান আরো বিস্তারিত জানার জন্য।
কেনি এভিট

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