Tôi đang thực hiện một số thử nghiệm bằng cách sử dụng lược tả SQL 2005.Truy vấn chạy nhanh, nhưng chạy chậm trong thủ tục được lưu trữ
Tôi có một thủ tục được lưu trữ chỉ cần chạy một truy vấn SQL.
Khi tôi chạy quy trình được lưu trữ, phải mất một thời gian dài và thực hiện 800.000 lần đọc đĩa.
Khi tôi chạy cùng một truy vấn riêng biệt với quy trình được lưu trữ, nó có 14.000 lần đọc đĩa.
Tôi thấy rằng nếu tôi chạy cùng một truy vấn với OPTION (biên dịch lại), phải mất 800.000 lần đọc đĩa.
Từ điều này, tôi làm cho giả định (có thể sai lầm) rằng thủ tục được lưu trữ được biên dịch lại mỗi lần và điều đó gây ra sự cố.
Có ai có thể làm sáng tỏ điều này không?
Tôi đã đặt ARITHABORT ON. (Điều này giải quyết một vấn đề tương tự trên stackoverflow, nhưng không giải quyết mỏ)
Dưới đây là toàn bộ thủ tục lưu trữ:
CREATE PROCEDURE [dbo].[GET_IF_SETTLEMENT_ADJUSTMENT_REQUIRED]
@Contract_ID int,
@dt_From smalldatetime,
@dt_To smalldatetime,
@Last_Run_Date datetime
AS
BEGIN
DECLARE @rv int
SELECT @rv = (CASE WHEN EXISTS
(
select * from
view_contract_version_last_volume_update
inner join contract_version
on contract_version.contract_version_id = view_contract_version_last_volume_update.contract_version_id
where [email protected]_ID
and volume_date >= @dt_From
and volume_date < @dt_To
and last_write_date > @Last_Run_Date
)
THEN 1 else 0 end)
-- Note that we are RETURNING a value rather than SELECTING it.
-- This means we can invoke this function from other stored procedures
return @rv
END
Dưới đây là một kịch bản tôi chạy đó chứng tỏ vấn đề:
DECLARE
@Contract_ID INT,
@dt_From smalldatetime,
@dt_To smalldatetime,
@Last_Run_Date datetime,
@rv int
SET @Contract_ID=38
SET @dt_From='2010-09-01'
SET @dt_To='2010-10-01'
SET @Last_Run_Date='2010-10-08 10:59:59:070'
-- This takes over fifteen seconds
exec GET_IF_SETTLEMENT_ADJUSTMENT_REQUIRED @[email protected]_ID,@[email protected]_From,@[email protected]_To,@[email protected]_Run_Date
-- This takes less than one second!
SELECT @rv = (CASE WHEN EXISTS
(
select * from
view_contract_version_last_volume_update
inner join contract_version
on contract_version.contract_version_id = view_contract_version_last_volume_update.contract_version_id
where [email protected]_ID
and volume_date >= @dt_From
and volume_date < @dt_To
and last_write_date > @Last_Run_Date
)
THEN 1 else 0 end)
-- With recompile option. Takes 15 seconds again!
SELECT @rv = (CASE WHEN EXISTS
(
select * from
view_contract_version_last_volume_update
inner join contract_version
on contract_version.contract_version_id = view_contract_version_last_volume_update.contract_version_id
where [email protected]_ID
and volume_date >= @dt_From
and volume_date < @dt_To
and last_write_date > @Last_Run_Date
)
THEN 1 else 0 end) OPTION(recompile)
Sự khác nhau giữa hai "Kế hoạch thực hiện truy vấn thực tế" là gì? – Andomar