মার্জ স্টেটমেন্টের জন্য আমার লকিং বিকল্পগুলি কী কী?


13

আমার কাছে একটি সঞ্চিত পদ্ধতি রয়েছে যা একটি MERGEবিবৃতি সম্পাদন করে ।

মনে হচ্ছে এটি মার্জ করার সময় ডিফল্টরূপে পুরো টেবিলটি লক করে।

আমি এই সঞ্চিত পদ্ধতিটি লেনদেনের অভ্যন্তরে কল করছি যেখানে আমি অন্যান্য কিছু জিনিসও করছি এবং আমি আশা করি এটি কেবল প্রভাবিত সারিগুলিকেই লক করে দেবে।

আমি ইঙ্গিতটি চেষ্টা করেছি MERGE INTO myTable WITH (READPAST)এবং মনে হচ্ছে এটি কম লক হয়ে গেছে। তবে এমএস ডকটিতে একটি সতর্কতা ছিল যা বলেছিল যে এটি প্রাথমিক কী এমনকি বাইপাস করে সদৃশ কী সন্নিবেশ করতে পারে।

এখানে আমার টেবিল স্কিমা:

CREATE TABLE StudentDetails
(
StudentID INTEGER PRIMARY KEY,
StudentName VARCHAR(15)
)
GO
INSERT INTO StudentDetails
VALUES(1,'WANG')
INSERT INTO StudentDetails
VALUES(2,'JOHNSON')
GO

CREATE TABLE StudentTotalMarks
(
Id INT IDENTITY PRIMARY KEY,
StudentID INTEGER REFERENCES StudentDetails,
StudentMarks INTEGER
)
GO
INSERT INTO StudentTotalMarks
VALUES(1,230)
INSERT INTO StudentTotalMarks
VALUES(2,255)
GO

এখানে আমার সঞ্চিত পদ্ধতি:

CREATE PROCEDURE MergeTest 
    @StudentId int,
    @Mark int
AS  

WITH Params
AS
(
    SELECT @StudentId as StudentId,
        @Mark as Mark
)
    MERGE StudentTotalMarks AS stm
    USING Params p
    ON stm.StudentID = p.StudentId
    WHEN MATCHED AND stm.StudentMarks > 250 THEN DELETE
    WHEN MATCHED THEN UPDATE SET stm.StudentMarks = p.Mark
    WHEN NOT MATCHED THEN
        INSERT(StudentID,StudentMarks)
        VALUES(p.StudentId, p.Mark);
GO

আমি এখানে লকিং পর্যবেক্ষণ করছি:

begin tran
EXEC MergeTest 1, 1

এবং তারপরে অন্য সেশনে:

EXEC MergeTest 2, 2

দ্বিতীয় অধিবেশন এগিয়ে যাওয়ার আগে প্রথম শেষ হওয়ার জন্য অপেক্ষা করে।


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

@ নিকচ্যামাস সাহায্যের জন্য আপনাকে ধন্যবাদ, আমি বিশদটি দিয়ে প্রশ্নটি আপডেট করেছি। আমি ভাবছি READPAST খারাপ হবে ...
জন বুচানান

উত্তর:


12

StudentTotalMarksরেকর্ডগুলি সনাক্ত করতে আপনাকে ক্যোয়ারী প্রসেসরকে আরও কার্যকর অ্যাক্সেসের পাথ দিতে হবে । যেমনটি লেখা হয়েছে, ক্যোয়ারিতে [StudentID] = [@StudentId]প্রতিটি সারিতে প্রয়োগ করা অবশিষ্টাংশের সাথে টেবিলের একটি পূর্ণ স্ক্যান প্রয়োজন :

স্ক্যান পরিকল্পনা

Uরূপান্তর ডেডলকগুলির একটি সাধারণ কারণের বিরুদ্ধে মৌলিক প্রতিরক্ষা হিসাবে পড়ার সময় ইঞ্জিনটি (আপডেট) লক নেয় । এই আচরণের অর্থ দ্বিতীয় নির্বাহের ব্লক যখন প্রথম নির্বাহের মাধ্যমে Uইতিমধ্যে একটি X(একচেটিয়া) লক দ্বারা লক করা সারিটিতে একটি লক পাওয়ার চেষ্টা করা হয় ।

নিম্নলিখিত সূচক অপ্রয়োজনীয় Uলকগুলি এড়ানো এড়িয়ে আরও ভাল অ্যাক্সেসের পথ সরবরাহ করে :

CREATE UNIQUE INDEX uq1 
ON dbo.StudentTotalMarks (StudentID) 
INCLUDE (StudentMarks);

ক্যোয়ারী পরিকল্পনায় এখন সিক অপারেশন অন্তর্ভুক্ত রয়েছে StudentID = [@StudentId], সুতরাং Uলকগুলি কেবলমাত্র লক্ষ্য সারিগুলিতে অনুরোধ করা হয়:

পরিকল্পনা সন্ধান করুন

ইস্যুটি হাতের কাছে সমাধানের জন্য সূচকের প্রয়োজন হয় না UNIQUE(যদিও INCLUDEএটি এই প্রশ্নের জন্য একটি কভারিং সূচক তৈরি করা প্রয়োজন) to

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

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