Eficiencia en Performance

23/03/2005 - 17:00 por Eduardo | Informe spam
Hola a todos. Tengo una pequeña preguntita a ver que
opinan uds. al respecto.
En un StoreProcedure que recibe parametros que es más
eficiente, verificar los datos de los parametros y
bifurcar con IF o verificarlos en la condición del SELECT.

Por ejemplo,

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
IF @IdValor = 0
SELECT * FROM TIPOS
ELSE
SELECT * FROM TIPOS WHERE IdValor = @IdValor
GO
*-*-*-*-*-*
Será más eficiente que:

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
SELECT * FROM TIPOS WHERE IdValor =
CASE WHEN @IdValor = THEN IdValor ELSE @IdValor END
GO


Me gustaría conocer cual es su opinión al respecto.
Saludos Cordiales y gracias por los comentarios

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
23/03/2005 - 17:49 | Informe spam
Eduardo,

Podrias comparar el plan de ejecucion de ambas versiones.

La primera opcion deberia, en este caso, dar mejor resultado. La expresion:

IdValor = CASE WHEN @IdValor = 0 THEN IdValor ELSE @IdValor END



obligaria a sql server a hacer un "scan" del indice (en caso de que
tuviera), en vez de un "seek" que es una operacion mas rapida. Aca te pongo
un ejemplo que puedes analyzar (fijate cuando se hace scan y cuando se hace
seek), incluyendo otra version del procedimiento que te podria servir si tu
tabla tiene un indice clustered por la columna usada en la clausula WHERE.
Tambien te adjunto un link a un articulo estupendo sobre este tema que es
busqueda dinamica.

Ejemplo:

use northwind
go

create procedure dbo.proc1
@par1 int = 0
as
set nocount on

if @par1 = 0
select * from orders
else
select * from orders where orderid = @par1

return @@error
go

create procedure dbo.proc2
@par1 int = 0
as
set nocount on

select * from orders where orderid = case when @par1 = 0 then orderid else
@par1 end

return @@error
go

create procedure dbo.proc3
@par1 int = 0
as
set nocount on

declare @min int
declare @max int

set @min = -2147483648
set @max = 2147483647

select *
from orders
where orderid between coalesce(nullif(@par1, 0), @min) and
coalesce(nullif(@par1, 0), @max)

return @@error
go

set showplan_text on
go

dbcc freeproccache
exec dbo.proc1
go

dbcc freeproccache
exec dbo.proc1 10250
go

dbcc freeproccache
exec dbo.proc2
go

dbcc freeproccache
exec dbo.proc2 10250
go

dbcc freeproccache
exec dbo.proc3
go

dbcc freeproccache
exec dbo.proc3 10250
go

set showplan_text off
go

drop procedure proc1, proc2
go

Dynamic Search Conditions in T-SQL
http://www.sommarskog.se/dyn-search.html


AMB


"Eduardo" wrote:

Hola a todos. Tengo una pequeña preguntita a ver que
opinan uds. al respecto.
En un StoreProcedure que recibe parametros que es más
eficiente, verificar los datos de los parametros y
bifurcar con IF o verificarlos en la condición del SELECT.

Por ejemplo,

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
IF @IdValor = 0
SELECT * FROM TIPOS
ELSE
SELECT * FROM TIPOS WHERE IdValor = @IdValor
GO
*-*-*-*-*-*
Será más eficiente que:

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
SELECT * FROM TIPOS WHERE IdValor =
CASE WHEN @IdValor = THEN IdValor ELSE @IdValor END
GO


Me gustaría conocer cual es su opinión al respecto.
Saludos Cordiales y gracias por los comentarios

Respuesta Responder a este mensaje
#2 MAXI
23/03/2005 - 23:40 | Informe spam
Hola, mi opinion que la opcion 2 es mas prolija y no creo que disminuya la
performance



Maxi
Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)



"Eduardo" escribió en el mensaje
news:060101c52fc1$8109bda0$
Hola a todos. Tengo una pequeña preguntita a ver que
opinan uds. al respecto.
En un StoreProcedure que recibe parametros que es más
eficiente, verificar los datos de los parametros y
bifurcar con IF o verificarlos en la condición del SELECT.

Por ejemplo,

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
IF @IdValor = 0
SELECT * FROM TIPOS
ELSE
SELECT * FROM TIPOS WHERE IdValor = @IdValor
GO
*-*-*-*-*-*
Será más eficiente que:

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
SELECT * FROM TIPOS WHERE IdValor CASE WHEN @IdValor = THEN IdValor ELSE @IdValor END
GO


Me gustaría conocer cual es su opinión al respecto.
Saludos Cordiales y gracias por los comentarios
Respuesta Responder a este mensaje
#3 Alejandro Mesa
24/03/2005 - 01:07 | Informe spam
Maxi,

Cuando uso la version 2, sql server decide hacer un scan del indice cuando
no pasas el valor (logico, queremos todas las filas) o cuando le pasas el
valor porque queremos una fila especifica. Esto no pasa con la version 1, sql
server hace un scan del indice cuando no pasamos un valor y hace un index
seek cuando pasamos un valor especifico. Quizas en una tabla como [orders],
que contiene 830 filas, no se note la diferencia entre hacer un seek a un
scan, pero en una tabla con un numero mayor si se veria. Puedes correr el
script que adjunto y chequear los planes de ejecucion.

use northwind
go

create procedure dbo.proc1
@par1 int = 0
as
set nocount on

if @par1 = 0
select * from orders
else
select * from orders where orderid = @par1

return @@error
go

create procedure dbo.proc2
@par1 int = 0
as
set nocount on

select * from orders where orderid = case when @par1 = 0 then orderid else
@par1 end

return @@error
go

set statistics profile on
go

dbcc freeproccache
exec proc1
go

dbcc freeproccache
exec proc1 10250
go

dbcc freeproccache
exec proc2
go
dbcc freeproccache
exec proc2 10250
go

set statistics profile off
go

drop procedure proc1, proc2
go


AMB

"MAXI" wrote:

Hola, mi opinion que la opcion 2 es mas prolija y no creo que disminuya la
performance



Maxi
Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)



"Eduardo" escribió en el mensaje
news:060101c52fc1$8109bda0$
Hola a todos. Tengo una pequeña preguntita a ver que
opinan uds. al respecto.
En un StoreProcedure que recibe parametros que es más
eficiente, verificar los datos de los parametros y
bifurcar con IF o verificarlos en la condición del SELECT.

Por ejemplo,

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
IF @IdValor = 0
SELECT * FROM TIPOS
ELSE
SELECT * FROM TIPOS WHERE IdValor = @IdValor
GO
*-*-*-*-*-*
Será más eficiente que:

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
SELECT * FROM TIPOS WHERE IdValor > CASE WHEN @IdValor = THEN IdValor ELSE @IdValor END
GO


Me gustaría conocer cual es su opinión al respecto.
Saludos Cordiales y gracias por los comentarios



Respuesta Responder a este mensaje
#4 MAXI
24/03/2005 - 03:09 | Informe spam
Ale, tenes toda la razon del mundo :-)



Maxi
Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)



"Alejandro Mesa" escribió en el
mensaje news:
Maxi,

Cuando uso la version 2, sql server decide hacer un scan del indice cuando
no pasas el valor (logico, queremos todas las filas) o cuando le pasas el
valor porque queremos una fila especifica. Esto no pasa con la version 1,
sql
server hace un scan del indice cuando no pasamos un valor y hace un index
seek cuando pasamos un valor especifico. Quizas en una tabla como
[orders],
que contiene 830 filas, no se note la diferencia entre hacer un seek a un
scan, pero en una tabla con un numero mayor si se veria. Puedes correr el
script que adjunto y chequear los planes de ejecucion.

use northwind
go

create procedure dbo.proc1
@par1 int = 0
as
set nocount on

if @par1 = 0
select * from orders
else
select * from orders where orderid = @par1

return @@error
go

create procedure dbo.proc2
@par1 int = 0
as
set nocount on

select * from orders where orderid = case when @par1 = 0 then orderid else
@par1 end

return @@error
go

set statistics profile on
go

dbcc freeproccache
exec proc1
go

dbcc freeproccache
exec proc1 10250
go

dbcc freeproccache
exec proc2
go
dbcc freeproccache
exec proc2 10250
go

set statistics profile off
go

drop procedure proc1, proc2
go


AMB

"MAXI" wrote:

Hola, mi opinion que la opcion 2 es mas prolija y no creo que disminuya
la
performance



Maxi
Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)



"Eduardo" escribió en el mensaje
news:060101c52fc1$8109bda0$
Hola a todos. Tengo una pequeña preguntita a ver que
opinan uds. al respecto.
En un StoreProcedure que recibe parametros que es más
eficiente, verificar los datos de los parametros y
bifurcar con IF o verificarlos en la condición del SELECT.

Por ejemplo,

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
IF @IdValor = 0
SELECT * FROM TIPOS
ELSE
SELECT * FROM TIPOS WHERE IdValor = @IdValor
GO
*-*-*-*-*-*
Será más eficiente que:

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
SELECT * FROM TIPOS WHERE IdValor >> CASE WHEN @IdValor = THEN IdValor ELSE @IdValor END
GO


Me gustaría conocer cual es su opinión al respecto.
Saludos Cordiales y gracias por los comentarios



Respuesta Responder a este mensaje
#5 MAXI
24/03/2005 - 03:14 | Informe spam
Un tema, en el query 1 veo que se ejecutan ambos y en el query 2 solo
siempre 1, si esto es asi habria que ver a grandes registros a la larga cual
es mas eficiente, parece ser el 1 porque hace en uno de sus querys un seek
pero en el otro siempre esta haciendo un scan ya que hace ambos por lo visto
:(


Me queda la duda :S



Maxi
Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)



"Alejandro Mesa" escribió en el
mensaje news:
Maxi,

Cuando uso la version 2, sql server decide hacer un scan del indice cuando
no pasas el valor (logico, queremos todas las filas) o cuando le pasas el
valor porque queremos una fila especifica. Esto no pasa con la version 1,
sql
server hace un scan del indice cuando no pasamos un valor y hace un index
seek cuando pasamos un valor especifico. Quizas en una tabla como
[orders],
que contiene 830 filas, no se note la diferencia entre hacer un seek a un
scan, pero en una tabla con un numero mayor si se veria. Puedes correr el
script que adjunto y chequear los planes de ejecucion.

use northwind
go

create procedure dbo.proc1
@par1 int = 0
as
set nocount on

if @par1 = 0
select * from orders
else
select * from orders where orderid = @par1

return @@error
go

create procedure dbo.proc2
@par1 int = 0
as
set nocount on

select * from orders where orderid = case when @par1 = 0 then orderid else
@par1 end

return @@error
go

set statistics profile on
go

dbcc freeproccache
exec proc1
go

dbcc freeproccache
exec proc1 10250
go

dbcc freeproccache
exec proc2
go
dbcc freeproccache
exec proc2 10250
go

set statistics profile off
go

drop procedure proc1, proc2
go


AMB

"MAXI" wrote:

Hola, mi opinion que la opcion 2 es mas prolija y no creo que disminuya
la
performance



Maxi
Buenos Aires - Argentina
Desarrollador .NET 3 Estrellas
Microsoft User Group (MUG)



"Eduardo" escribió en el mensaje
news:060101c52fc1$8109bda0$
Hola a todos. Tengo una pequeña preguntita a ver que
opinan uds. al respecto.
En un StoreProcedure que recibe parametros que es más
eficiente, verificar los datos de los parametros y
bifurcar con IF o verificarlos en la condición del SELECT.

Por ejemplo,

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
IF @IdValor = 0
SELECT * FROM TIPOS
ELSE
SELECT * FROM TIPOS WHERE IdValor = @IdValor
GO
*-*-*-*-*-*
Será más eficiente que:

CREATE PROCEDURE dbo.Store1
@IdValor INT = 0
AS
SELECT * FROM TIPOS WHERE IdValor >> CASE WHEN @IdValor = THEN IdValor ELSE @IdValor END
GO


Me gustaría conocer cual es su opinión al respecto.
Saludos Cordiales y gracias por los comentarios



Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida