پروسیجرها و شنود پارامترها در SQL Server - قسمت دوم
نویسنده: امیر هاشم زاده
تاریخ: ۱۳۹۵/۰۹/۰۱ ۹:۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
شنود پارامتر، قابلیتی است که اس کیو ال سرور توسط آن یک پلن مناسب و بهینه اجرایی را برای پروسیجری با پارامترهای ارسالی، در اولین مرتبه اجرا، تولید خواهد کرد. در ادامه هر فراخوانی پروسیجر با پارامترهای مشابه، منجر به استفاده از پلن اجرایی ذخیره شده خواهد شد. شاید در اولین نگاه این استفاده مجدد، مناسب به نظر برسد. ولی در صورتیکه پروسیجر با پارامترهای متفاوتی فراخوانی شود، ممکن است پلن اجرایی تولید شده بر اساس آن پارامترهای اولیه، برای پارامترهای جدید بهینه نباشد.
پلنهای اجرایی بر اساس چیزهایی که از SQL Server خواسته میشوند، بهینه سازی میشوند. اس کیو ال سرور کوئری را بررسی کرده و یک استراتژی بهینه را برای اجرای آن مشخص میکند. به کارهایی که کوئری قرار است انجام دهد نگاه میکند؛ از مقادیر پارامترها برای استفاده از اطلاعات آماری استفاده کرده و محاسباتی را انجام خواهد داد.
در ادامه، برای درک بهتر شنود پارامتر، با مثالی خواهید دید که پروسیجر ذیل، باعث مصرف بالای منابع، بر اساس پارامترهای ارسالی خواهد شد. در این مثال دو دسته متفاوت پارامتر برای اجرای پروسیجر ارسال خواهند شد و خواهید دید که فراخوانی دوم، منابع I/O بیشتری را نسبت به فراخوانی اول، مصرف خواهد کرد. در ادامه کدهای جدولی را که پروسیجر قرار است بر روی آن فراخوانی اطلاعات را انجام دهد، میبینید.
SET NOCOUNT ON;
DROP TABLE BillingInfo;
CREATE TABLE BillingInfo(
ID INT IDENTITY,
BillingDate DATETIME,
BillingAmt MONEY,
BillingDesc varchar(500));
DECLARE @I INT;
DECLARE @BD INT;
SET @I = 0;
WHILE @I < 1000000
BEGIN
SET @I = @I + 1;
SET @BD=CAST(RAND()*10000 AS INT)%3650;
INSERT BillingInfo (BillingDate, BillingAmt)
VALUES (DATEADD(DD,@BD,
CAST('1999/01/01' AS DATETIME)),
RAND()*5000);
END
ALTER TABLE BillingInfo
ADD CONSTRAINT [PK_BillingInfo_ID]
PRIMARY KEY CLUSTERED (ID);
CREATE NONCLUSTERED INDEX IX_BillingDate
ON dbo.BillingInfo(BillingDate); در جدول BilingInfo بالا، یک میلیون رکورد با مقادیر BilingDate و BilingAmt به صورت تصادفی ایجاد شده است. بر روی ستون ID، ایندکس خوشهای و ستون ایندکس غیر خوشهای بر روی ستون BilingDate ایجاد شدهاست.
بوسیله پروسیجر زیر هم قرار است اطلاعات درخواستی فراهم شود:
CREATE PROC [dbo].[DisplayBillingInfo] @BeginDate DATETIME, @EndDate DATETIME AS SELECT BillingDate, BillingAmt FROM BillingInfo WHERE BillingDate between @BeginDate AND @EndDate;
SET STATISTICS IO ON; DBCC FREEPROCCACHE; EXEC dbo.DisplayBillingInfo @BeginDate = '1999-01-01', @EndDate = '1999-12-31'; EXEC dbo.DisplayBillingInfo @BeginDate = '2005-01-01', @EndDate = '2005-01-03';
Table 'BillingInfo'. Scan count 1, logical reads 3593, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'BillingInfo'. Scan count 1, logical reads 3593, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
SET STATISTICS IO ON; DBCC FREEPROCCACHE; EXEC dbo.DisplayBillingInfo @BeginDate = '2005-01-01', @EndDate = '2005-01-03'; EXEC dbo.DisplayBillingInfo @BeginDate = '1999-01-01', @EndDate = '1999-12-31';
اکنون عملیات Index Seek را بجای Index Scan مشاهده میکنید. اطلاعات I/O هم بشرح زیر است:
Table 'BillingInfo'. Scan count 1, logical reads 2965, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. Table 'BillingInfo'. Scan count 1, logical reads 337040, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.