Estoy haciendo algunas pruebas con el generador de perfiles SQL 2005.La consulta se ejecuta rápidamente, pero se ejecuta lentamente en el procedimiento almacenado
Tengo un procedimiento almacenado que simplemente ejecuta una consulta SQL.
Cuando ejecuto el procedimiento almacenado, se necesita mucho tiempo y realiza 800.000 lecturas de disco.
Cuando ejecuto la misma consulta separada al procedimiento almacenado, lo hace 14.000 lecturas de disco.
He descubierto que si corro la misma consulta con la opción (recompilación), se necesita 800.000 lecturas de disco.
partir de esto, hago la suposición (posiblemente errónea) de que el procedimiento almacenado se recompilando cada vez, y que está causando el problema.
¿Alguien puede arrojar algo de luz sobre esto?
He establecido ARITHABORT ON. (Esto resolvió un problema similar en stackoverflow, pero no resolvió el mío)
Aquí es todo el procedimiento almacenado:
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
Aquí es un script corro que demuestra el problema:
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)
¿Cuál es la diferencia entre los dos "Planes de ejecución de consultas reales"? – Andomar