Verificar si una tablatiene datos ...

29/10/2007 - 20:36 por Peni | Informe spam
Que es más rápido en general, hacer un select count(*)... where o un
select top 1 ... where?


=Saludos. Peni.
=

Preguntas similare

Leer las respuestas

#16 Alfredo Novoa
30/10/2007 - 13:13 | Informe spam
On Mon, 29 Oct 2007 13:26:07 -0700, Alejandro Mesa
wrote:

Para eso existe el operador EXISTS.

if EXISTS(select * from tu_tabla)
...

No hace falta seleccionar o contar para probar existencia en una tabla.



Si, bastante más elegante.


Saludos
Respuesta Responder a este mensaje
#17 Alejandro Mesa
30/10/2007 - 14:18 | Informe spam
jeastman - Hotmail,

Espero que hayas limpiado el cache de data antes de ejecutar cada sentencia,
de lo contrario no estas siendo justo.

use tu_db
go

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

if (select count(*) from tu_tabla) > 0
print 'tiene filas'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

if exists(select * from tu_tabla)
print 'tiene filas'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

IF EXISTS(SELECT TOP 1 * FROM tu_tabla)
print 'tiene filas'
go


AMB

"jeastman - Hotmail" wrote:

Señores.

Me tomé la libertad de hacer la prueba que sugiere el compañero José
Mariano, para ello creé una tabla con 2.342.560 de registros y sin ningún
indice primero y luego con un índice clustered, las pruebas las hice en el
mismo orden que las mostró el compañero y los resultados fueron los
siguiente:


SIN ÍNDICES
=> count(*) (4080) milisegundos
select 1 (7156) milisegundos
select top 1 * (13) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (16) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (4033) milisegundos


CON ÍNDICE CLUSTERED
==> count(*) (10923) milisegundos
select 1 (12310) milisegundos
select top 1 * (46) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (13) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (11690) milisegundos

Los resultados demuestran que existen dos opciones que supera a cualquier
otra con o sin índices

1) select top 1 1 (0) milisegundos
2) if exists(select 1 from aaa ) print 'tiene filas' else print 'NO tiene
filas'

Aqui les anexo el script que utilicé para la prueba

Saludos a todos.


P.D. Si alguien obtiene algún resultado diferente, me gustaría conocer los
resultados.

Este es el script de la tabla
CREATE TABLE aaa (
CorrelMovimiento int NOT NULL ,
CodEstructura int NOT NULL ,
CodPartida int NOT NULL ,
CodUsuario int NOT NULL ,
NroPresupuesto int NOT NULL ,
TipoMovimiento tinyint NOT NULL ,
PresupuestoOrd money NOT NULL ,
FIDES money NOT NULL ,
LAES money NOT NULL ,
Otras money NOT NULL ,
Observacion varchar (255) NOT NULL ,
FechaAgregado datetime NOT NULL ,
FechaCierre datetime NOT NULL
)


y el índice lo hice por los campos correlMovimiento y nroPresupuesto, estaba
seguro que podía hacer un índice único por esos valores


y el íindice lo hice
> declare @inicio datetime,
@fin datetime,
@dif int



DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select count(*) from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'count(*) (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 * from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 * (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select * from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select *... (' + cast( @dif as varchar ) + ')
milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select 1 from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select 1... (' + cast( @dif as varchar ) + ')
milisegundos'


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if (select count(*) from aaa ) > 0 print 'tiene filas'
else print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if (select count(*)...) > 0 (' + cast( @dif as varchar ) + ')
milisegundos'
>

"Jose Mariano Alvarez"
escribió en el
mensaje news:e%
> Los dos son igualmente malos.
> Es mejor como dice alejandro, usando TOP 1 o usando el cuantificador
> existencial.
>
> Prueba esto con la base de datos de ejemplo y mira los pesos relativos.
>
> select count(*) from dbo.FactInternetSales
> select 1 from dbo.FactInternetSales
> select top 1 * from dbo.FactInternetSales
> select top 1 1 from dbo.FactInternetSales
> if exists(select * from dbo.FactInternetSales ) print 'tiene filas' else
> print 'NO tiene filas'
> if exists(select 1 from dbo.FactInternetSales ) print 'tiene filas' else
> print 'NO tiene filas'
> if (select count(*) from dbo.FactInternetSales ) > 0 print 'tiene filas'
> else print 'NO tiene filas'
>
>
>
> Saludos
> Ing. Jose Mariano Alvarez
>
>
> (Cambia los ceros por O y saca lo que sobra)
>
>
> IMPORTANTE
>
> Por favor traten de indicar la versión de SQL y Service Pack.
> La inclusión de (CREATE, INSERTS, etc.) para poder reproducir el problema
> también ayuda.
>
>
>
> "jeastman - Hotmail" wrote in message
> news:e%238$
>> Hola.
>>
>> Yo hice una prueba con éstas dos versiones:
>>
>> select count(*) from tabla
>>
>> y la segunda versión fue:
>>
>> if exists (select 1 from tabla)
>> begin
>> print 'Existe'
>> end
>>
>> La tabla es muy pequeña, solo tiene 73.205 registros
>>
>> En la primera forma me dio un segundo, en la segunda no llegó al segundo.
>>
>> Yo personalmente utilizo la segunda alternativa, pues le dejo el trabajo
>> al obtimizador de buscar la mejor manera de averiguar si hay o no
>> registros, el 1 que está en el select es para evitar colocar un * que en
>> éste caso no hace falta.
>>
>> Si obtienen otros resultados y alguna mejor vía me gustaría conocerla y
>> así evitarle trabajo al motor.
>>
>> Saludos.
>>
>> "Leonardo Azpurua" <l e o n a r d o [arroba] m v p s [punto] o r g>
>> escribió en el mensaje news:
>>>
>>> "Penta" escribió en el mensaje
>>> news:
>>>> Con el top de toda maneras, si haces un count(*) de una tabla de
>>>> muchos registros = se toma su tiempo.
>>>
>>> Igual hay quien sabe mas que nosotros de SQL Server y me corrige, pero
>>> creo que el COUNT(*) lo unico que hace es examinar el descriptor de la
>>> tabla, o sea que debe ser mucho más rápido.
>>>
>>> Salud!
>>>
>>>
>>
>>
>
>



Respuesta Responder a este mensaje
#18 Alejandro Mesa
30/10/2007 - 14:29 | Informe spam
jeastman - Hotmail,

Ya veo que fuistes justo en cuanto a limpiar el cache de data y
procedimientos. Una cosa mas me hubiese gustado que chequearas, y son los
planes de ejecucion de cada sentencia. Si los planes son diferentes, entonces
vale medir el tiempo, de lo contrario deberian dar igual resultado. Recuerda
que otros procesos pueden estar ocurriendo en la maquina de pruebas, no solo
procesos disparados por el usuario sino tambien procesos propios de SQL
Server como LAZY WRITER, etc, o procesos del propios del sistema operativo y
eso seria la causa de la diferencia de tiempo entre dos sentencias con igual
plan de ejcucion, puesto que esos procesos no corren continuamente sino que
se disparan cada cierto tiempo y si por casualidad se disparo en una
sentencia y no en la otra entonces veremos diferencias de tiempo para planes
de ejecucion iguales.


AMB


"jeastman - Hotmail" wrote:

Señores.

Me tomé la libertad de hacer la prueba que sugiere el compañero José
Mariano, para ello creé una tabla con 2.342.560 de registros y sin ningún
indice primero y luego con un índice clustered, las pruebas las hice en el
mismo orden que las mostró el compañero y los resultados fueron los
siguiente:


SIN ÍNDICES
=> count(*) (4080) milisegundos
select 1 (7156) milisegundos
select top 1 * (13) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (16) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (4033) milisegundos


CON ÍNDICE CLUSTERED
==> count(*) (10923) milisegundos
select 1 (12310) milisegundos
select top 1 * (46) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (13) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (11690) milisegundos

Los resultados demuestran que existen dos opciones que supera a cualquier
otra con o sin índices

1) select top 1 1 (0) milisegundos
2) if exists(select 1 from aaa ) print 'tiene filas' else print 'NO tiene
filas'

Aqui les anexo el script que utilicé para la prueba

Saludos a todos.


P.D. Si alguien obtiene algún resultado diferente, me gustaría conocer los
resultados.

Este es el script de la tabla
CREATE TABLE aaa (
CorrelMovimiento int NOT NULL ,
CodEstructura int NOT NULL ,
CodPartida int NOT NULL ,
CodUsuario int NOT NULL ,
NroPresupuesto int NOT NULL ,
TipoMovimiento tinyint NOT NULL ,
PresupuestoOrd money NOT NULL ,
FIDES money NOT NULL ,
LAES money NOT NULL ,
Otras money NOT NULL ,
Observacion varchar (255) NOT NULL ,
FechaAgregado datetime NOT NULL ,
FechaCierre datetime NOT NULL
)


y el índice lo hice por los campos correlMovimiento y nroPresupuesto, estaba
seguro que podía hacer un índice único por esos valores


y el íindice lo hice
> declare @inicio datetime,
@fin datetime,
@dif int



DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select count(*) from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'count(*) (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 * from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 * (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select * from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select *... (' + cast( @dif as varchar ) + ')
milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select 1 from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select 1... (' + cast( @dif as varchar ) + ')
milisegundos'


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if (select count(*) from aaa ) > 0 print 'tiene filas'
else print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if (select count(*)...) > 0 (' + cast( @dif as varchar ) + ')
milisegundos'
>

"Jose Mariano Alvarez"
escribió en el
mensaje news:e%
> Los dos son igualmente malos.
> Es mejor como dice alejandro, usando TOP 1 o usando el cuantificador
> existencial.
>
> Prueba esto con la base de datos de ejemplo y mira los pesos relativos.
>
> select count(*) from dbo.FactInternetSales
> select 1 from dbo.FactInternetSales
> select top 1 * from dbo.FactInternetSales
> select top 1 1 from dbo.FactInternetSales
> if exists(select * from dbo.FactInternetSales ) print 'tiene filas' else
> print 'NO tiene filas'
> if exists(select 1 from dbo.FactInternetSales ) print 'tiene filas' else
> print 'NO tiene filas'
> if (select count(*) from dbo.FactInternetSales ) > 0 print 'tiene filas'
> else print 'NO tiene filas'
>
>
>
> Saludos
> Ing. Jose Mariano Alvarez
>
>
> (Cambia los ceros por O y saca lo que sobra)
>
>
> IMPORTANTE
>
> Por favor traten de indicar la versión de SQL y Service Pack.
> La inclusión de (CREATE, INSERTS, etc.) para poder reproducir el problema
> también ayuda.
>
>
>
> "jeastman - Hotmail" wrote in message
> news:e%238$
>> Hola.
>>
>> Yo hice una prueba con éstas dos versiones:
>>
>> select count(*) from tabla
>>
>> y la segunda versión fue:
>>
>> if exists (select 1 from tabla)
>> begin
>> print 'Existe'
>> end
>>
>> La tabla es muy pequeña, solo tiene 73.205 registros
>>
>> En la primera forma me dio un segundo, en la segunda no llegó al segundo.
>>
>> Yo personalmente utilizo la segunda alternativa, pues le dejo el trabajo
>> al obtimizador de buscar la mejor manera de averiguar si hay o no
>> registros, el 1 que está en el select es para evitar colocar un * que en
>> éste caso no hace falta.
>>
>> Si obtienen otros resultados y alguna mejor vía me gustaría conocerla y
>> así evitarle trabajo al motor.
>>
>> Saludos.
>>
>> "Leonardo Azpurua" <l e o n a r d o [arroba] m v p s [punto] o r g>
>> escribió en el mensaje news:
>>>
>>> "Penta" escribió en el mensaje
>>> news:
>>>> Con el top de toda maneras, si haces un count(*) de una tabla de
>>>> muchos registros = se toma su tiempo.
>>>
>>> Igual hay quien sabe mas que nosotros de SQL Server y me corrige, pero
>>> creo que el COUNT(*) lo unico que hace es examinar el descriptor de la
>>> tabla, o sea que debe ser mucho más rápido.
>>>
>>> Salud!
>>>
>>>
>>
>>
>
>



Respuesta Responder a este mensaje
#19 jeastman - Hotmail
30/10/2007 - 14:33 | Informe spam
Hola Alejandro.

Si revisas más abajo veras en el script que he limpiado la caché como tú
sugieres y Alfredo.

De todos modos, si observas algo mal en la prueba, por favor emite las
modificaciones que hay que hacer y con gusto repito la prueba, aun tengo la
tabla.

Gracias por tu comentario

Saludos.

"Alejandro Mesa" escribió en el
mensaje news:
jeastman - Hotmail,

Espero que hayas limpiado el cache de data antes de ejecutar cada
sentencia,
de lo contrario no estas siendo justo.

use tu_db
go

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

if (select count(*) from tu_tabla) > 0
print 'tiene filas'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

if exists(select * from tu_tabla)
print 'tiene filas'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE

IF EXISTS(SELECT TOP 1 * FROM tu_tabla)
print 'tiene filas'
go


AMB

"jeastman - Hotmail" wrote:

Señores.

Me tomé la libertad de hacer la prueba que sugiere el compañero José
Mariano, para ello creé una tabla con 2.342.560 de registros y sin ningún
indice primero y luego con un índice clustered, las pruebas las hice en
el
mismo orden que las mostró el compañero y los resultados fueron los
siguiente:


SIN ÍNDICES
=>> count(*) (4080) milisegundos
select 1 (7156) milisegundos
select top 1 * (13) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (16) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (4033) milisegundos


CON ÍNDICE CLUSTERED
==>> count(*) (10923) milisegundos
select 1 (12310) milisegundos
select top 1 * (46) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (13) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (11690) milisegundos

Los resultados demuestran que existen dos opciones que supera a cualquier
otra con o sin índices

1) select top 1 1 (0) milisegundos
2) if exists(select 1 from aaa ) print 'tiene filas' else print 'NO tiene
filas'

Aqui les anexo el script que utilicé para la prueba

Saludos a todos.


P.D. Si alguien obtiene algún resultado diferente, me gustaría conocer
los
resultados.

Este es el script de la tabla
CREATE TABLE aaa (
CorrelMovimiento int NOT NULL ,
CodEstructura int NOT NULL ,
CodPartida int NOT NULL ,
CodUsuario int NOT NULL ,
NroPresupuesto int NOT NULL ,
TipoMovimiento tinyint NOT NULL ,
PresupuestoOrd money NOT NULL ,
FIDES money NOT NULL ,
LAES money NOT NULL ,
Otras money NOT NULL ,
Observacion varchar (255) NOT NULL ,
FechaAgregado datetime NOT NULL ,
FechaCierre datetime NOT NULL
)


y el índice lo hice por los campos correlMovimiento y nroPresupuesto,
estaba
seguro que podía hacer un índice único por esos valores


y el íindice lo hice
>> declare @inicio datetime,
@fin datetime,
@dif int



DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select count(*) from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'count(*) (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 * from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 * (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select * from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select *... (' + cast( @dif as varchar ) + ')
milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select 1 from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select 1... (' + cast( @dif as varchar ) + ')
milisegundos'


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if (select count(*) from aaa ) > 0 print 'tiene filas'
else print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if (select count(*)...) > 0 (' + cast( @dif as varchar ) + ')
milisegundos'
>>

"Jose Mariano Alvarez"
escribió en el
mensaje news:e%
> Los dos son igualmente malos.
> Es mejor como dice alejandro, usando TOP 1 o usando el cuantificador
> existencial.
>
> Prueba esto con la base de datos de ejemplo y mira los pesos relativos.
>
> select count(*) from dbo.FactInternetSales
> select 1 from dbo.FactInternetSales
> select top 1 * from dbo.FactInternetSales
> select top 1 1 from dbo.FactInternetSales
> if exists(select * from dbo.FactInternetSales ) print 'tiene filas'
> else
> print 'NO tiene filas'
> if exists(select 1 from dbo.FactInternetSales ) print 'tiene filas'
> else
> print 'NO tiene filas'
> if (select count(*) from dbo.FactInternetSales ) > 0 print 'tiene
> filas'
> else print 'NO tiene filas'
>
>
>
> Saludos
> Ing. Jose Mariano Alvarez
>
>
> (Cambia los ceros por O y saca lo que sobra)
>
>
> IMPORTANTE
>
> Por favor traten de indicar la versión de SQL y Service Pack.
> La inclusión de (CREATE, INSERTS, etc.) para poder reproducir el
> problema
> también ayuda.
>
>
>
> "jeastman - Hotmail" wrote in message
> news:e%238$
>> Hola.
>>
>> Yo hice una prueba con éstas dos versiones:
>>
>> select count(*) from tabla
>>
>> y la segunda versión fue:
>>
>> if exists (select 1 from tabla)
>> begin
>> print 'Existe'
>> end
>>
>> La tabla es muy pequeña, solo tiene 73.205 registros
>>
>> En la primera forma me dio un segundo, en la segunda no llegó al
>> segundo.
>>
>> Yo personalmente utilizo la segunda alternativa, pues le dejo el
>> trabajo
>> al obtimizador de buscar la mejor manera de averiguar si hay o no
>> registros, el 1 que está en el select es para evitar colocar un * que
>> en
>> éste caso no hace falta.
>>
>> Si obtienen otros resultados y alguna mejor vía me gustaría conocerla
>> y
>> así evitarle trabajo al motor.
>>
>> Saludos.
>>
>> "Leonardo Azpurua" <l e o n a r d o [arroba] m v p s [punto] o r g>
>> escribió en el mensaje news:
>>>
>>> "Penta" escribió en el mensaje
>>> news:
>>>> Con el top de toda maneras, si haces un count(*) de una tabla de
>>>> muchos registros = se toma su tiempo.
>>>
>>> Igual hay quien sabe mas que nosotros de SQL Server y me corrige,
>>> pero
>>> creo que el COUNT(*) lo unico que hace es examinar el descriptor de
>>> la
>>> tabla, o sea que debe ser mucho más rápido.
>>>
>>> Salud!
>>>
>>>
>>
>>
>
>



Respuesta Responder a este mensaje
#20 jeastman - Hotmail
30/10/2007 - 14:58 | Informe spam
Efectivamente, existen muchos factores que influyen en el rendimiento, en mi
caso hice la prueba en un laptop, con MSDE 2000, la DB no está atendiendo a
nadie en éste momento, salvo que sus propias actividades, sería interesante
verificar lo que dices y mejor en un servidor en producción, mi prueba
digamos que fue de laboratorio, ahora, lo que si hice fue ejecutarlo varias
veces cada uno de las dos presentaciones que hice y pasé al grupo, por lo
menos unas 10 veces ejecuté cada uno y la diferencias de tiempo no las noté,
y los que tenían peor tiempo lo mantuvieron y lo que tenían mejor tiempo
también lo mantuvieron.

De todos modos me parece interesante tu propuesta, por ahora voy a revisar
los planes de ejecución en mi Laptop, y cuando vaya a algún cliente
realizaré la prueba con un servidor en prueba.

Ahora, si alguien puede haces la prueba que sugiere Alfredo se le agradece.

Gracias por tu comentario Alejandro.

Saludos.

"Alejandro Mesa" escribió en el
mensaje news:
jeastman - Hotmail,

Ya veo que fuistes justo en cuanto a limpiar el cache de data y
procedimientos. Una cosa mas me hubiese gustado que chequearas, y son los
planes de ejecucion de cada sentencia. Si los planes son diferentes,
entonces
vale medir el tiempo, de lo contrario deberian dar igual resultado.
Recuerda
que otros procesos pueden estar ocurriendo en la maquina de pruebas, no
solo
procesos disparados por el usuario sino tambien procesos propios de SQL
Server como LAZY WRITER, etc, o procesos del propios del sistema operativo
y
eso seria la causa de la diferencia de tiempo entre dos sentencias con
igual
plan de ejcucion, puesto que esos procesos no corren continuamente sino
que
se disparan cada cierto tiempo y si por casualidad se disparo en una
sentencia y no en la otra entonces veremos diferencias de tiempo para
planes
de ejecucion iguales.


AMB


"jeastman - Hotmail" wrote:

Señores.

Me tomé la libertad de hacer la prueba que sugiere el compañero José
Mariano, para ello creé una tabla con 2.342.560 de registros y sin ningún
indice primero y luego con un índice clustered, las pruebas las hice en
el
mismo orden que las mostró el compañero y los resultados fueron los
siguiente:


SIN ÍNDICES
=>> count(*) (4080) milisegundos
select 1 (7156) milisegundos
select top 1 * (13) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (16) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (4033) milisegundos


CON ÍNDICE CLUSTERED
==>> count(*) (10923) milisegundos
select 1 (12310) milisegundos
select top 1 * (46) milisegundos
select top 1 1 (0) milisegundos
if exists (select *... (13) milisegundos
if exists (select 1... (0) milisegundos
if (select count(*)...) > 0 (11690) milisegundos

Los resultados demuestran que existen dos opciones que supera a cualquier
otra con o sin índices

1) select top 1 1 (0) milisegundos
2) if exists(select 1 from aaa ) print 'tiene filas' else print 'NO tiene
filas'

Aqui les anexo el script que utilicé para la prueba

Saludos a todos.


P.D. Si alguien obtiene algún resultado diferente, me gustaría conocer
los
resultados.

Este es el script de la tabla
CREATE TABLE aaa (
CorrelMovimiento int NOT NULL ,
CodEstructura int NOT NULL ,
CodPartida int NOT NULL ,
CodUsuario int NOT NULL ,
NroPresupuesto int NOT NULL ,
TipoMovimiento tinyint NOT NULL ,
PresupuestoOrd money NOT NULL ,
FIDES money NOT NULL ,
LAES money NOT NULL ,
Otras money NOT NULL ,
Observacion varchar (255) NOT NULL ,
FechaAgregado datetime NOT NULL ,
FechaCierre datetime NOT NULL
)


y el índice lo hice por los campos correlMovimiento y nroPresupuesto,
estaba
seguro que podía hacer un índice único por esos valores


y el íindice lo hice
>> declare @inicio datetime,
@fin datetime,
@dif int



DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select count(*) from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'count(*) (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 * from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 * (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select top 1 1 from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'select top 1 1 (' + cast( @dif as varchar ) + ') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select * from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select *... (' + cast( @dif as varchar ) + ')
milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if exists(select 1 from aaa ) print 'tiene filas' else
print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if exists (select 1... (' + cast( @dif as varchar ) + ')
milisegundos'


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
if (select count(*) from aaa ) > 0 print 'tiene filas'
else print 'NO tiene filas'
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print 'if (select count(*)...) > 0 (' + cast( @dif as varchar ) + ')
milisegundos'
>>

"Jose Mariano Alvarez"
escribió en el
mensaje news:e%
> Los dos son igualmente malos.
> Es mejor como dice alejandro, usando TOP 1 o usando el cuantificador
> existencial.
>
> Prueba esto con la base de datos de ejemplo y mira los pesos relativos.
>
> select count(*) from dbo.FactInternetSales
> select 1 from dbo.FactInternetSales
> select top 1 * from dbo.FactInternetSales
> select top 1 1 from dbo.FactInternetSales
> if exists(select * from dbo.FactInternetSales ) print 'tiene filas'
> else
> print 'NO tiene filas'
> if exists(select 1 from dbo.FactInternetSales ) print 'tiene filas'
> else
> print 'NO tiene filas'
> if (select count(*) from dbo.FactInternetSales ) > 0 print 'tiene
> filas'
> else print 'NO tiene filas'
>
>
>
> Saludos
> Ing. Jose Mariano Alvarez
>
>
> (Cambia los ceros por O y saca lo que sobra)
>
>
> IMPORTANTE
>
> Por favor traten de indicar la versión de SQL y Service Pack.
> La inclusión de (CREATE, INSERTS, etc.) para poder reproducir el
> problema
> también ayuda.
>
>
>
> "jeastman - Hotmail" wrote in message
> news:e%238$
>> Hola.
>>
>> Yo hice una prueba con éstas dos versiones:
>>
>> select count(*) from tabla
>>
>> y la segunda versión fue:
>>
>> if exists (select 1 from tabla)
>> begin
>> print 'Existe'
>> end
>>
>> La tabla es muy pequeña, solo tiene 73.205 registros
>>
>> En la primera forma me dio un segundo, en la segunda no llegó al
>> segundo.
>>
>> Yo personalmente utilizo la segunda alternativa, pues le dejo el
>> trabajo
>> al obtimizador de buscar la mejor manera de averiguar si hay o no
>> registros, el 1 que está en el select es para evitar colocar un * que
>> en
>> éste caso no hace falta.
>>
>> Si obtienen otros resultados y alguna mejor vía me gustaría conocerla
>> y
>> así evitarle trabajo al motor.
>>
>> Saludos.
>>
>> "Leonardo Azpurua" <l e o n a r d o [arroba] m v p s [punto] o r g>
>> escribió en el mensaje news:
>>>
>>> "Penta" escribió en el mensaje
>>> news:
>>>> Con el top de toda maneras, si haces un count(*) de una tabla de
>>>> muchos registros = se toma su tiempo.
>>>
>>> Igual hay quien sabe mas que nosotros de SQL Server y me corrige,
>>> pero
>>> creo que el COUNT(*) lo unico que hace es examinar el descriptor de
>>> la
>>> tabla, o sea que debe ser mucho más rápido.
>>>
>>> Salud!
>>>
>>>
>>
>>
>
>



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