এই দুটি ফাংশন বিবেচনা করুন:
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);
তারপরে অতিরিক্ত সাজান আবার হাজির!
কেউ কিছু আলোকপাত করতে পারে? এখানে অপটিমাইজারে কী চলছে?