আমি কি দুটি টেবিলে একটি সরগেবল প্রথম অক্ষর ম্যাচ করতে পারি?


9
select value 
from persons p join persons2 p2 
    on left(p.lastname,1) = left(p2.lastname,1)

SQL সার্ভার. এই SARGable / দ্রুত চালানোর কোন উপায় আছে? আমি ব্যক্তি টেবিলে কলাম তৈরি করতে পারি না, তবে আমি ব্যক্তি 2 এ কলাম তৈরি করতে পারি।


3
আপনি জানেন যে এই ক্যোয়ারির ফলাফলটি আসলে এক ধরণের ক্রস যোগ হতে চলেছে?
ypercubeᵀᴹ

1
টেবিলগুলি কত বড়? যদি তারা প্রত্যেকে কেবল 10 কে সারি বলে, ফলাফল কমপক্ষে 4 মিলিয়ন সারি হবে। আমি ভাবছি যে এই জাতীয় ক্যোয়ারির ব্যবহার কী হবে।
ypercubeᵀᴹ

1
@ ইয়পারকিউবᵀᴹ ফাজি ম্যাচিং ব্যবহার করে কিছু নকল প্রক্রিয়া শুরু হতে পারে?
মার্টিন স্মিথ

খারাপ ধারণা মত শোনাচ্ছে। আপনি এখানে কি অর্জন করার চেষ্টা করছেন?
ডেভিড דודו মার্কোভিটস

এটি কেবল উদাহরণস্বরূপ ছিল। আরও পূর্বাভাস আছে। মার্টিন স্মিথের সঠিক ধারণা আছে, এটি প্রতিলিপি দেওয়ার জন্য।
লাস্টচ্যান্সেক্সি

উত্তর:


9

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 | সর্বোচ্চ | ভার্নন | ভি |
+ + ---------- + + ----------- + + ---------- + + --------------- - + + ---------- + + ----------- + + ---------- + + ------------- ---- + +

টেবিলের জন্য মাত্র দুটি সারি দিয়ে কার্যকর করার পরিকল্পনা (স্বীকার করা হয় যে অনেকগুলি সারি নয়!)

এখানে চিত্র বর্ণনা লিখুন


11

যদি 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

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


এই পদ্ধতির সম্পর্কে কি ? এটির কোনও সুবিধা থাকলে আপনার উত্তরে এটিকে নির্দ্বিধায় যোগ করুন। এটি কি উভয় টেবিলের সূচী ব্যবহার করবে - এবং যদি তাই হয় তবে এটি আরও কার্যকর হবে?
ypercubeᵀᴹ

@ ypercubeᵀᴹ যদি সূচিগুলি i.stack.imgur.com/RSzcT.png আচ্ছাদন করে তবে এটি এটির মতো একটি পরিকল্পনা দিতে পারে । যদিও আমি আমার উত্তরে পরিকল্পনার চেয়ে কোনও সুবিধা দেখছি না। এটি এখনও বাইরের টেবিলের সমস্ত সারি পড়ার প্রয়োজনীয়তা শেষ করবে, এখন কেবল একটি স্ক্যানের চেয়ে ২ 26 টি সন্ধানের মাধ্যমে।
মার্টিন স্মিথ

2

আমি 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 মিমি অবস্হায়।

এখানে চিত্র বর্ণনা লিখুন

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