আমার কাছে এটি উপস্থিত হয় যে where
ক্যোয়ারির ধারাটি সমস্যাটি দিচ্ছে, এবং এটি যদি কম OPTION(RECOMPILE)
ব্যবহার করা হয় তবে কম অনুমানের কারণ ।
আমি কিছু পরীক্ষার ডেটা তৈরি করেছি এবং শেষ পর্যন্ত দুটি সমাধান নিয়ে এসেছি, ID
ক্ষেত্রটি resources
হয় একটি ভেরিয়েবলের (যদি এটি সর্বদা অনন্য থাকে) বা একটি টেম্প টেবিল থেকে সংগ্রহ করে থাকে, যদি আমাদের একের বেশি থাকতে পারে ID
।
বেস পরীক্ষার রেকর্ড
SET NOCOUNT ON
DECLARE @i int= 1;
WHILE @i <= 10000
BEGIN
INSERT INTO [dbo].[Settings]([resourceId],[typeID],remark)
VALUES(@i,@i,'KEPT THESE VALUES OUT BECAUSE IT WOULD CLUTTER THE EXAMPLES, VALUES OVER 8000 Chars entered here'); -- 23254 character length on each value
INSERT INTO [dbo].[Resources](resourceUID)
VALUES(@i);
SET @i += 1;
END
ওপির মতো প্রায় আনুমানিক ফলাফলসীমার জন্য 'সিক' মানগুলি সন্নিবেশ করান (১৩০০ রেকর্ডস)
INSERT INTO [dbo].[Settings]([resourceId],[typeID],remark)
VALUES(38,38,'KEPT THESE VALUES OUT BECAUSE IT WOULD CLUTTER THE EXAMPLES, VALUES OVER 8000 Chars entered here')
GO 1300
ওপিকে ম্যাচ করার জন্য কমপ্যাট এবং আপডেটের পরিসংখ্যান পরিবর্তন করুন
ALTER DATABASE StackOverflow SET COMPATIBILITY_LEVEL = 120;
UPDATE STATISTICS settings WITH FULLSCAN;
UPDATE STATISTICS resources WITH FULLSCAN;
মূল ক্যোয়ারী
exec sp_executesql N'
select r.id
FROM Resources r
inner join Settings on resourceid=r.id
where resourceUID=@UID
ORDER BY typeID',
N'@UID int',
@UID=38
আমার অনুমানগুলি আরও খারাপ , এক অনুমান সারি সহ, যখন ১৩০০ ফেরত পাওয়া যায়। এবং ওপি যেমন বলেছে, আমি যুক্ত করলে তাতে কিছু আসে যায় নাOPTION(RECOMPILE)
একটি গুরুত্বপূর্ণ বিষয় লক্ষণীয়, হ'ল আমরা যখন ক্লজটি থেকে অনুমান করলাম তখন অনুমানগুলি 100% সঠিক, যা প্রত্যাশা করা হয় যেহেতু আমরা উভয় সারণীতে সমস্ত ডেটা ব্যবহার করছি।
আমি সূচিগুলিকে কেবল পূর্ববর্তী ক্যোয়ারির মতো একই বিষয়গুলি ব্যবহার করার বিষয়টি নিশ্চিত করতে বাধ্য করেছিলাম, বিষয়টি প্রমাণ করতে
exec sp_executesql N'
select r.id,remark
FROM Resources r with(index([IX_UID]))
inner join Settings WITH(INDEX([IX_Test]))
on resourceid=r.id
ORDER BY typeID',
N'@UID int',
@UID=38
প্রত্যাশিত হিসাবে, ভাল অনুমান।
সুতরাং, আরও ভাল অনুমানের জন্য আমরা কী পরিবর্তন করতে পারি তবে এখনও আমাদের মূল্যবোধগুলি সন্ধান করতে পারি?
যদি @ নির্দেশটি অনন্য, যেমন যেমন ওপি দিয়েছে, আমরা id
যে এককটি resources
ভেরিয়েবল থেকে ফেরত পেয়েছিলাম তা রাখতে পারি, তারপরে সেই বিকল্পটি একটি বিকল্প (পুনরুদ্ধার) দিয়ে সন্ধান করতে পারি
DECLARE @UID int =38 , @RID int;
SELECT @RID=r.id from
Resources r where resourceUID = @UID;
SELECT @uid, remark
from Settings
where resourceId = @uid
Order by typeID
OPTION(RECOMPILE);
যা 100% সঠিক অনুমান দেয়
তবে কি যদি একাধিক রিসোর্সইউড রিসোর্সে থাকে?
কিছু পরীক্ষার ডেটা যুক্ত করুন
INSERT INTO Resources(ResourceUID)
VALUES (38);
go 50
এটি একটি টেম্প টেবিল দিয়ে সমাধান করা যেতে পারে
CREATE TABLE #RID (id int)
DECLARE @UID int =38
INSERT INTO #RID
SELECT r.id
from
Resources r where resourceUID = @UID
SELECT @uid, remark
from Settings s
INNER JOIN #RID r
ON r.id =s.resourceId
Order by typeID
OPTION(RECOMPILE)
DROP TABLE #RID
আবার সঠিক অনুমান সহ ।
এটি আমার নিজস্ব ডেটাসেট, ওয়াইএমএমভি দিয়ে করা হয়েছিল।
Sp_executesql দিয়ে লেখা
একটি পরিবর্তনশীল সহ
exec sp_executesql N'
DECLARE @RID int;
SELECT @RID=r.id from
Resources r where resourceUID = @UID;
SELECT @uid, remark
from Settings
where resourceId = @uid
Order by typeID
OPTION(RECOMPILE);',
N'@UID int',
@UID=38
একটি টেম্প টেবিল সহ
exec sp_executesql N'
CREATE TABLE #RID (id int)
INSERT INTO #RID
SELECT r.id
from
Resources r where resourceUID = @UID
SELECT @uid, remark
from Settings s
INNER JOIN #RID r
ON r.id =s.resourceId
Order by typeID
OPTION(RECOMPILE)
DROP TABLE #RID',
N'@UID int',
@UID=38
আমার পরীক্ষায় এখনও 100% সঠিক অনুমান
select r.id, LEFT(remark, 512)
(বা বোধগম্য স্ট্রিংয়ের দৈর্ঘ্য যাই হোক না কেন)।