ROW_NUMBER () ওভার (বি এর পার্টিশন বি, একটি অর্ডার বাই অর্ডার) (এ, বি, সি) এর উপর সূচক ব্যবহার করে না


12

এই দুটি ফাংশন বিবেচনা করুন:

ROW_NUMBER() OVER (PARTITION BY A,B ORDER BY C)

ROW_NUMBER() OVER (PARTITION BY B,A ORDER BY C)

আমি যতদূর বুঝতে পারি, তারা ঠিক একই ফলাফল উত্পাদন করে। অন্য কথায়, আপনি ধারাটিতে কলামগুলি যে ক্রমে তালিকাভুক্ত PARTITION BYকরছেন তাতে কিছু আসে যায় না।

যদি কোনও সূচক থাকে তবে (A,B,C)আমি আশা করি যে অপটিমাইজার উভয় ভেরিয়েন্টে এই সূচকটি ব্যবহার করবে।

তবে, আশ্চর্যজনকভাবে, অপটিমাইজার দ্বিতীয় ভেরিয়েন্টে একটি অতিরিক্ত স্পষ্টরূপে বাছাই করার সিদ্ধান্ত নিয়েছে।

আমি এটি এসকিউএল সার্ভার 2008 স্ট্যান্ডার্ড এবং এসকিউএল সার্ভার 2014 এক্সপ্রেসে দেখেছি।

এখানে একটি সম্পূর্ণ স্ক্রিপ্ট যা আমি এটি পুনরুত্পাদন করতাম।

মাইক্রোসফ্ট এসকিউএল সার্ভারে চেষ্টা করা হয়েছে 2014 - 12.0.2000.8 (X64) ফেব্রুয়ারী 20 2014 20:04:26 কপিরাইট (সি) উইন্ডোজ এনটি 6.1 তে মাইক্রোসফ্ট কর্পোরেশন এক্সপ্রেস সংস্করণ (-৪-বিট) (বিল্ড 7601: সার্ভিস প্যাক 1)

এবং মাইক্রোসফ্ট এসকিউএল সার্ভার 2014 (এসপি 1-সিইউ 7) (কেবি 3162659) - 12.0.4459.0 (এক্স 64) মে 27 2016 15:33:17 কপিরাইট (সি) মাইক্রোসফ্ট কর্পোরেশন এক্সপ্রেস সংস্করণ (64৪-বিট) উইন্ডোজ এনটি 6.1 (বিল্ড 7601: পরিষেবা) প্যাক 1)

পুরানো এবং নতুন উভয় কার্ডিনালিটির অনুমান ব্যবহার করে OPTION (QUERYTRACEON 9481)এবং এর মাধ্যমে OPTION (QUERYTRACEON 2312)

সারণী, সূচক, নমুনা ডেটা সেট আপ করুন

CREATE TABLE [dbo].[T](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [A] [int] NOT NULL,
    [B] [int] NOT NULL,
    [C] [int] NOT NULL,
    CONSTRAINT [PK_T] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, 
STATISTICS_NORECOMPUTE = OFF, 
IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, 
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE NONCLUSTERED INDEX [IX_ABC] ON [dbo].[T]
(
    [A] ASC,
    [B] ASC,
    [C] ASC
)WITH (PAD_INDEX = OFF, 
STATISTICS_NORECOMPUTE = OFF, 
SORT_IN_TEMPDB = OFF, 
DROP_EXISTING = OFF, 
ONLINE = OFF, 
ALLOW_ROW_LOCKS = ON, 
ALLOW_PAGE_LOCKS = ON)
GO

INSERT INTO [dbo].[T] ([A],[B],[C]) VALUES
(10, 20, 30),
(10, 21, 31),
(10, 21, 32),
(10, 21, 33),
(11, 20, 34),
(11, 21, 35),
(11, 21, 36),
(12, 20, 37),
(12, 21, 38),
(13, 21, 39);

ক্যোয়ারী

SELECT -- AB
    ID,A,B,C
    ,ROW_NUMBER() OVER (PARTITION BY A,B ORDER BY C) AS rnAB
FROM T
ORDER BY C
OPTION(RECOMPILE);

SELECT -- BA
    ID,A,B,C
    ,ROW_NUMBER() OVER (PARTITION BY B,A ORDER BY C) AS rnBA
FROM T
ORDER BY C
OPTION(RECOMPILE);

SELECT -- both
    ID,A,B,C
    ,ROW_NUMBER() OVER (PARTITION BY A,B ORDER BY C) AS rnAB
    ,ROW_NUMBER() OVER (PARTITION BY B,A ORDER BY C) AS rnBA
FROM T
ORDER BY C
OPTION(RECOMPILE);

কার্যকর করার পরিকল্পনা রয়েছে

এ, বি দ্বারা পার্টিশন

এবি

বি দ্বারা ভাগ, ক

বি। এ

উভয়

উভয়

আপনি দেখতে পাচ্ছেন, দ্বিতীয় পরিকল্পনায় একটি অতিরিক্ত বাছাই হয়েছে। এটি বি, এ, সি দ্বারা অর্ডার করে। অপটিমাইজার, দৃশ্যতঃ স্মার্ট যথেষ্ট উপলব্ধি করা নয় PARTITION BY B,Aহিসাবে একই PARTITION BY A,Bএবং ডেটা পুনরায় বাছাই করে।

মজার বিষয় হল, তৃতীয় ক্যোয়ারিতে এর উভয় রূপ রয়েছে ROW_NUMBERএবং কোনও অতিরিক্ত বাছাই করা নেই! পরিকল্পনাটি প্রথম ক্যোয়ারির মতোই। (সিকোয়েন্স প্রজেক্টের অতিরিক্ত কলামের আউটপুট তালিকায় অতিরিক্ত প্রকাশ রয়েছে তবে অতিরিক্ত বাছাই করা নেই)। সুতরাং, এই আরও জটিল ক্ষেত্রে অপটিমাইজারটি যথেষ্ট স্মার্ট বলে মনে হয়েছিল যে PARTITION BY B,Aএটি একই রকম PARTITION BY A,B

প্রথম এবং তৃতীয় প্রশ্নের ইনডেক্স স্ক্যান অপারেটরের সম্পত্তি অর্ডার হয়েছে: সত্য, দ্বিতীয় ক্যোয়ারিতে এটি মিথ্যা।

আরও আকর্ষণীয়, যদি আমি এই জাতীয় তৃতীয় কোয়েরিটি আবার লিখি (দুটি কলাম পরিবর্তন করব):

SELECT -- both
    ID,A,B,C
    ,ROW_NUMBER() OVER (PARTITION BY B,A ORDER BY C) AS rnBA
    ,ROW_NUMBER() OVER (PARTITION BY A,B ORDER BY C) AS rnAB
FROM T
ORDER BY C
OPTION(RECOMPILE);

তারপরে অতিরিক্ত সাজান আবার হাজির!

কেউ কিছু আলোকপাত করতে পারে? এখানে অপটিমাইজারে কী চলছে?


উত্তর:


2

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

আমি এখানে মন্তব্য একসাথে করব।

সামগ্রিকভাবে, এটি মনে হয় এটি একটি বাগ বলা খুব কঠোর হবে, কারণ ক্যোয়ারির শেষ ফলাফলটি সঠিক is কিছু ক্ষেত্রে মৃত্যুদন্ড কার্যকর করার পরিকল্পনাটি সর্বোত্তম নয়। ইয়ারকিউবে , মার্টিন স্মিথ এবং অ্যারন বার্ট্র্যান্ড এটিকে "মিস অপটিমাইজেশন" বলেছেন।

  • দেখে মনে হচ্ছে GROUP BY a,bএবং GROUP BY b,aঅভিন্ন পরিকল্পনা দেয় তবে PARTITION BYএকই রূপান্তর ব্যবহার করতে পারে না

  • অন্যান্য নিখোঁজ অপ্টিমাইজেশন রয়েছে যেখানে একই উইন্ডো স্পেসিফিকেশন সহ উইন্ডো ফাংশনগুলির একটি পৃথক স্পেসিফিকেশন সহ একের দ্বারা নির্বাচিত তালিকায় পৃথক করা হলে একটি অতিরিক্ত সাজানোর ক্রিয়াকলাপ করতে পারে।

  • হ্যাঁ, এটি অন্য মিসড অপটিমাইজেশনের মতো মনে হয় এবং এর প্রচুর পরিমাণ রয়েছে। অপটিমাইজারটি মানুষ লিখেছেন এবং নিখুঁত নয়


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


আমার কাছে ব্যবহারিক ফলাফলটি আশাবাদীর এই বিশেষত্বটি মাথায় রাখাই হবে। PARTITION BYউইন্ডো ফাংশনগুলিতে ব্যবহার করার সময় সর্বদা আপনি যে কলামগুলিকে PARTITION BYসূচীতে তালিকাভুক্ত করা হয়েছে সেই ক্রমের সাথে তালিকায় থাকা ক্রমের সাথে মিলানোর চেষ্টা করুন । যদিও এটি করা উচিত নয়।

এই সতর্কতার আরেকটি দিক হ'ল আপনি যখন আপনার সূচীগুলি পর্যালোচনা করেন এবং সূচী সংজ্ঞা অনুসারে কয়েকটি কলাম পরিবর্তন করতে চান। সচেতন হোন যে আপনি অজান্তেই কিছু বিদ্যমান প্রশ্নগুলিকে প্রভাবিত করতে পারেন যা আপাতদৃষ্টিতে প্রভাবিত হবে না। অপ্টিমাইজারের এই বিশেষত্বটি আমি কীভাবে লক্ষ্য করেছি actually

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

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