এসকিউএল সার্ভার কেন কেবলমাত্র একটি সারি আনতে হবে যদিও সারণীতে প্রতিটি মানের জন্য ব্যবহারকারীর সংজ্ঞায়িত ফাংশনটি কল করার সিদ্ধান্ত নেয় তা বুঝতে আমার সমস্যা হয়। আসল এসকিউএল অনেক বেশি জটিল, তবে আমি সমস্যাটি এখানে কমাতে সক্ষম হয়েছি:
select
S.GROUPCODE,
H.ORDERCATEGORY
from
ORDERLINE L
join ORDERHDR H on H.ORDERID = L.ORDERID
join PRODUCT P on P.PRODUCT = L.PRODUCT
cross apply dbo.GetGroupCode (P.FACTORY) S
where
L.ORDERNUMBER = 'XXX/YYY-123456' and
L.RMPHASE = '0' and
L.ORDERLINE = '01'
এই ক্যোয়ারির জন্য, এসকিউএল সার্ভার অর্ডারলাইন থেকে প্রাপ্ত সারিগুলির অনুমান এবং প্রকৃত সংখ্যা 1 (যদিও এটি প্রাথমিক কী) যদিও উত্পাদিত সারণীতে বিদ্যমান প্রতিটি একক মানের জন্য getGroupCode ফাংশন কল করার সিদ্ধান্ত নিয়েছে:
পরিকল্পনার এক্সপ্লোরার একই পরিকল্পনার সারি গণনা দেখায়:
টেবিল:
ORDERLINE: 1.5M rows, primary key: ORDERNUMBER + ORDERLINE + RMPHASE (clustered)
ORDERHDR: 900k rows, primary key: ORDERID (clustered)
PRODUCT: 6655 rows, primary key: PRODUCT (clustered)
স্ক্যানের জন্য ব্যবহৃত সূচকটি হ'ল:
create unique nonclustered index PRODUCT_FACTORY on PRODUCT (PRODUCT, FACTORY)
ফাংশনটি আসলে কিছুটা জটিল, তবে একই জিনিসটি ডামি মাল্টি-স্টেটমেন্ট ফাংশনটির সাথে ঘটে:
create function GetGroupCode (@FACTORY varchar(4))
returns @t table(
TYPE varchar(8),
GROUPCODE varchar(30)
)
as begin
insert into @t (TYPE, GROUPCODE) values ('XX', 'YY')
return
end
এসকিউএল সার্ভারকে শীর্ষ 1 পণ্য আনতে বাধ্য করে আমি পারফরম্যান্সটি "ফিক্স" করতে সক্ষম হয়েছি, যদিও 1 সর্বাধিক যা সন্ধান করা যায়:
select
S.GROUPCODE,
H.ORDERCAT
from
ORDERLINE L
join ORDERHDR H
on H.ORDERID = M.ORDERID
cross apply (select top 1 P.FACTORY from PRODUCT P where P.PRODUCT = L.PRODUCT) P
cross apply dbo.GetGroupCode (P.FACTORY) S
where
L.ORDERNUMBER = 'XXX/YYY-123456' and
L.RMPHASE = '0' and
L.ORDERLINE = '01'
তারপরে পরিকল্পনার আকারটিও এমন কিছুতে পরিবর্তিত হয় যা আমি প্রত্যাশা করি এটি মূলত:
আমি আরও জানালাম যে, ক্লাস্টারযুক্ত সূচকের তুলনায় PRODUCT_FACTORY সূচকটি PRODUCT_PK এর চেয়ে ছোট হবে তবে তারপরেও উত্পাদনটি জিজ্ঞাসাবাদকে PRODUCT_PK ব্যবহার করতে বাধ্য করা সত্ত্বেও, ফাংশনটিতে 6655 কল সহ পরিকল্পনাটি এখনও মূল হিসাবে একই।
যদি আমি ORDERHDR পুরোপুরি ছেড়ে চলে যাই তবে প্রথমে অর্ডারলাইন এবং প্রোডাক্টের মধ্যে নেস্টেড লুপ দিয়ে প্ল্যান শুরু হবে এবং ফাংশনটি কেবল একবার ডাকা হবে।
আমি বুঝতে চাই যে এর কারণগুলি কী হতে পারে যেহেতু প্রাথমিক কীগুলি ব্যবহার করে সমস্ত ক্রিয়াকলাপ সম্পন্ন হয় এবং কীভাবে এটি ঠিক করা যায় যদি এটি আরও জটিল প্রশ্নে ঘটে তবে এটি সহজে সমাধান করা যায় না।
সম্পাদনা করুন: সারণী বিবৃতি তৈরি করুন:
CREATE TABLE dbo.ORDERHDR(
ORDERID varchar(8) NOT NULL,
ORDERCATEGORY varchar(2) NULL,
CONSTRAINT ORDERHDR_PK PRIMARY KEY CLUSTERED (ORDERID)
)
CREATE TABLE dbo.ORDERLINE(
ORDERNUMBER varchar(16) NOT NULL,
RMPHASE char(1) NOT NULL,
ORDERLINE char(2) NOT NULL,
ORDERID varchar(8) NOT NULL,
PRODUCT varchar(8) NOT NULL,
CONSTRAINT ORDERLINE_PK PRIMARY KEY CLUSTERED (ORDERNUMBER,ORDERLINE,RMPHASE)
)
CREATE TABLE dbo.PRODUCT(
PRODUCT varchar(8) NOT NULL,
FACTORY varchar(4) NULL,
CONSTRAINT PRODUCT_PK PRIMARY KEY CLUSTERED (PRODUCT)
)