select value
from persons p join persons2 p2
on left(p.lastname,1) = left(p2.lastname,1)
SQL সার্ভার. এই SARGable / দ্রুত চালানোর কোন উপায় আছে? আমি ব্যক্তি টেবিলে কলাম তৈরি করতে পারি না, তবে আমি ব্যক্তি 2 এ কলাম তৈরি করতে পারি।
select value
from persons p join persons2 p2
on left(p.lastname,1) = left(p2.lastname,1)
SQL সার্ভার. এই SARGable / দ্রুত চালানোর কোন উপায় আছে? আমি ব্যক্তি টেবিলে কলাম তৈরি করতে পারি না, তবে আমি ব্যক্তি 2 এ কলাম তৈরি করতে পারি।
উত্তর:
LEFT(lastname, 1)প্রতিটি টেবিলের হিসাবে নির্ধারিত স্থায়ী গণিত কলাম সহ টেবিলগুলিতে একটি ভিউ তৈরি করুন , তারপরে গণিত স্থায়ী কলাম মানগুলির তুলনা করুন।
এটি কীভাবে করবেন তা দেখানোর জন্য এখানে একটি পরীক্ষার শয্যা রয়েছে:
CREATE TABLE dbo.Persons
(
PersonID int NOT NULL
CONSTRAINT PK_Persons
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, FirstName nvarchar(500) NOT NULL
, LastName nvarchar(500) NOT NULL
);
CREATE TABLE dbo.Persons2
(
PersonID int NOT NULL
CONSTRAINT PK_Persons2
PRIMARY KEY CLUSTERED
IDENTITY(1,1)
, FirstName nvarchar(500) NOT NULL
, LastName nvarchar(500) NOT NULL
);
GO
CREATE VIEW dbo.PersonsView
WITH SCHEMABINDING
AS
SELECT p1.PersonID
, p1.FirstName
, p1.LastName
, LastNameInitial = LEFT(p1.LastName, 1)
FROM dbo.Persons p1;
GO
CREATE VIEW dbo.PersonsView2
WITH SCHEMABINDING
AS
SELECT p2.PersonID
, p2.FirstName
, p2.LastName
, LastNameInitial = LEFT(p2.LastName, 1)
FROM dbo.Persons p2;
GO
CREATE UNIQUE CLUSTERED INDEX CX_PersonsView
ON dbo.PersonsView(PersonID);
CREATE NONCLUSTERED INDEX IX_PersonsView_LastNameInitial
ON dbo.PersonsView(LastNameInitial)
INCLUDE (FirstName, LastName);
CREATE UNIQUE CLUSTERED INDEX CX_PersonsView2
ON dbo.PersonsView2(PersonID);
CREATE NONCLUSTERED INDEX IX_PersonsView2_LastNameInitial
ON dbo.PersonsView2(LastNameInitial)
INCLUDE (FirstName, LastName);
CREATE STATISTICS ST_PersonsView_001
ON dbo.PersonsView(LastName);
CREATE STATISTICS ST_PersonsView2_001
ON dbo.PersonsView2(LastName);
এখানে, আমরা কিছু নমুনা তথ্য সন্নিবেশ করব:
INSERT INTO dbo.Persons(FirstName, LastName)
VALUES ('Max', 'Vernon')
, ('Joe', 'Black');
INSERT INTO dbo.Persons2(FirstName, LastName)
VALUES ('Max', 'Vernon')
, ('Joe', 'Black');
SELECTকোয়েরিটি এখানে :
SELECT *
FROM dbo.PersonsView pv1
INNER JOIN dbo.PersonsView2 pv2 ON pv1.LastNameInitial = pv2.LastNameInitial;
এবং ফলাফল:
+ + ---------- + + ----------- + + ---------- + + --------------- - + + ---------- + + ----------- + + ---------- + + ------------- ---- + + | ব্যক্তি | প্রথম নাম | সর্বশেষ নাম | লাস্টনেমআইনিটিয়াল | ব্যক্তি | প্রথম নাম | সর্বশেষ নাম | লাস্টনেমআইনিটিয়াল | + + ---------- + + ----------- + + ---------- + + --------------- - + + ---------- + + ----------- + + ---------- + + ------------- ---- + + | 2 | জো | কালো | খ | 2 | জো | কালো | খ | | 1 | সর্বোচ্চ | ভার্নন | ভি | 1 | সর্বোচ্চ | ভার্নন | ভি | + + ---------- + + ----------- + + ---------- + + --------------- - + + ---------- + + ----------- + + ---------- + + ------------- ---- + +
টেবিলের জন্য মাত্র দুটি সারি দিয়ে কার্যকর করার পরিকল্পনা (স্বীকার করা হয় যে অনেকগুলি সারি নয়!)
যদি lastnameকলামটি কমপক্ষে একটি সারণিতে সূচিত হয় তবে আপনি এটিও ব্যবহার করতে পারেনLIKE
SELECT *
FROM persons p
INNER JOIN persons2 p2
ON p2.lastname LIKE LEFT(p.lastname, 1) + '%'
এটির জন্য পরিকল্পনার মতো বামে নির্দিষ্ট টেবিলের উপরে থাকা সন্ধান করা যেতে পারে।
অর্থাত উপরোক্ত যে ON p.lastname LIKE LEFT(p2.lastname, 1) + '%'সূচকটি ব্যবহার হয়েছিল তা ব্যবহার করতে সক্ষম হবে না persons2তবে এটির সন্ধান করতে পারেpersons ।
উভয় পক্ষের গণনাকৃত কলামকে সূচকের অন্য উত্তরের পরামর্শটি তবে আরও নমনীয়। যেমন কোনও নেস্টেড লুপস পরিকল্পনার জন্য কোনও টেবিলটি অভ্যন্তরে থাকতে পারে এবং এটি অনেককে অনেকগুলি একত্রিত করার জন্য বাছাই করার অনুমতি দেয়।
আমি 3,423 সারি এবং 195 টি স্বতন্ত্র মান সহ একটি টেবিল পেয়েছি Name। আমি এই টেবিলটিকে P(ব্যক্তি) কল করব এবং এটি তৈরির জন্য সদৃশ করব P2person একটি পূর্ণসংখ্যা আইডি কলামে একটি অনন্য, ক্লাস্টারযুক্ত প্রাথমিক কী রয়েছে। আমি 32 গিগাবাইট র্যাম সহ উইন্ডোজ 10 প্রো 6.3 এ মাইক্রোসফ্ট এসকিউএল সার্ভার 2016 (KB3194716) বিকাশকারী সংস্করণ (-৪-বিট) ব্যবহার করছি।
বেস কোয়েরি সহ
select
p.pid
from dbo.p
inner join dbo.p2
on LEFT(p.name, 1) = LEFT(p2.name, 1);
আমি 1.500 সারি 3200-3300ms এ ফিরে পেয়েছি (পরিসংখ্যান থেকে io)।
এইভাবে পুনরায় লেখার মাধ্যমে -
select
p.pid
from dbo.p
where exists
(
select 1
from dbo.p2
where LEFT(p.name, 1) = LEFT(p2.name, 1)
);
অতিবাহিত হ্রাস 50-60ms এবং পরিকল্পনাটি হ'ল:
মিলে যাওয়া অ্যালগরিদমের কারণে কম সারিগুলি (3,423) ফেরত দেওয়া হয়েছে। বেস ক্যোয়ারীতে পরিবর্তন করে একই পরিকল্পনা এবং সারি গণনা অর্জন করা হয় select distinct।
সূচকযুক্ত, গণিত কলাম তৈরি করে
alter table dbo.p2
add Name1 as Left(Name, 1);
create index ix1 on dbo.p2(Name1);
অতিবাহিত সময় 45-50 মিমি অবস্হায়।