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

#21 jeastman - Hotmail
30/10/2007 - 15:11 | Informe spam
Hola Alejandro.

Acabo de verificar el plan de ejecución.

Si existen diferencias en el plan de ejecución, hay un par de casos de
similitudes, pero las opciones más rápidas tienen planes iguales entre ellas
pero con diferencias notables al resto.

No se si es lo que estabas pidiendo, espero tu opinión.

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
#22 jeastman - Hotmail
30/10/2007 - 15:39 | Informe spam
Dosculpen...


En la primera presentación de resultados y en la anterior respuesta a
Alejandro obvié algunos resultados, los anoto a continuación:

Los dos primeros son los sugerido por Ruben, los demás fueron la sugerencia
de Alejandro.

1) SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id = o.id
WHERE o.name = 'aaa' and i.indid = 1 (16) milisegundos
2) SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID('aaa') AND indid = 1
(0) milisegundos
3) select count(*) from aaa (10940) milisegundos
4) select 1 from aaa (11860) milisegundos
5) select top 1 * from aaa (80) milisegundos
6) select top 1 1 from aaa (0) milisegundos
7) if exists(select * from aaa ) print 'tiene filas' else print 'NO tiene
filas' (0) milisegundos
8) if exists(select 1 from aaa ) print 'tiene filas' else print 'NO tiene
filas' (0) milisegundos
9) if (select count(*) from aaa ) > 0 print 'tiene filas' else print 'NO
tiene filas' (11623) milisegundos

La corrida de evaluación de tiempo fue ejecutada sin visualizar el plan de
ejecución para no tomar en cuenta los tiempos requerido para ello.

Como podemos observar las sentencias ( 2, 6, 7, 8 ) obtuvieron los mejores
tiempo, no con ello se puede ignorar otras opciones que tienen tiempo muy
bajos.

Ahora, en cuanto a los planes de ejecución, solo comentaré el de los cuatro
mejores tiempos:

Las sentencias 2 y 6 son diferentes entre si y diferente a la 7 y la 8, las
cuales si son iguales entre ellos (los planes), a la vez que el 6 si es
igual 5, aun cuando el 5 tuvo un resultado un poco menor pero que no es
despreciable.

El plan de jecución de las consultas 7 y 8 son iguales.

Ahora, lo que no tomé en cuenta para éste análisis fue los números
individuales de cada uno de los componentes del plan de ejecución, jejeje,
tengo que trabajar mis disculpas.

No se si esto sea suficiente con los resultados obtenidos hasta ahora.

Saludos.

P.D. El script de la última prueba es la siguiente:

==--Número de registros 2.342.560
declare @inicio datetime,
@fin datetime,
@dif int



DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id = o.id
WHERE o.name = 'aaa' and i.indid = 1
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '1) SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id
= o.id WHERE o.name = ''aaa'' and i.indid = 1 (' + cast( @dif as varchar ) +
') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID('aaa') AND indid = 1
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '2) SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID(''aaa'') AND
indid = 1 (' + cast( @dif as varchar ) + ') milisegundos'


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select count(*) from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '3) select count(*) from aaa (' + 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 '4) select 1 from aaa (' + 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 '5) select top 1 * from aaa (' + 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 '6) select top 1 1 from aaa (' + 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 '7) if exists(select * from aaa ) print ''tiene filas'' else print
''NO tiene filas'' (' + 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 '8) if exists(select 1 from aaa ) print ''tiene filas'' else print
''NO tiene filas'' (' + 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 '9) if (select count(*) from aaa ) > 0 print ''tiene filas'' else
print ''NO tiene filas'' (' + cast( @dif as varchar ) + ') milisegundos'
==

"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
#23 Penta
30/10/2007 - 16:12 | Informe spam
Estimado.
El costo relativo respecto al batch es:
1ra opcion
99.93%
2da y 3ra opcion 0.03%

Como se lee esto? o mejor dicho que quiere decir exactamente ?

Atte.
Penta.
Respuesta Responder a este mensaje
#24 Alejandro Mesa
30/10/2007 - 16:55 | Informe spam
jeastman - Hotmail,

OK, como me temia, la 7 y 8 tienen igual plan de ejecucion, por lo que no
debe haber diferencia de tiempo entre ellas. Si cuando ejecutamos ambas
sentencias (limpiando los cache) vemos alguna diferencia,m entonces debe
haber algun proceso corriendo que no afecta igualmente ambas sentencias.

Producto de estos procesos que se ejecutan detras del telon, lo que se suele
hacer es correr, por decir, la sentencia 7 (limpiando los caches por cada
corrida), digameos unas 1000 o mas veces, gurdando los tiempos en una tabla,
luego se calcula el promedio. No creo que sea necesario para esta prueba,
pues es conocido que debemos usar el operador EXISTS para probar existencia,
creo que el nombre del operador nos lo indica explicitamente.

AMB

"jeastman - Hotmail" wrote:

Dosculpen...


En la primera presentación de resultados y en la anterior respuesta a
Alejandro obvié algunos resultados, los anoto a continuación:

Los dos primeros son los sugerido por Ruben, los demás fueron la sugerencia
de Alejandro.

1) SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id = o.id
WHERE o.name = 'aaa' and i.indid = 1 (16) milisegundos
2) SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID('aaa') AND indid = 1
(0) milisegundos
3) select count(*) from aaa (10940) milisegundos
4) select 1 from aaa (11860) milisegundos
5) select top 1 * from aaa (80) milisegundos
6) select top 1 1 from aaa (0) milisegundos
7) if exists(select * from aaa ) print 'tiene filas' else print 'NO tiene
filas' (0) milisegundos
8) if exists(select 1 from aaa ) print 'tiene filas' else print 'NO tiene
filas' (0) milisegundos
9) if (select count(*) from aaa ) > 0 print 'tiene filas' else print 'NO
tiene filas' (11623) milisegundos

La corrida de evaluación de tiempo fue ejecutada sin visualizar el plan de
ejecución para no tomar en cuenta los tiempos requerido para ello.

Como podemos observar las sentencias ( 2, 6, 7, 8 ) obtuvieron los mejores
tiempo, no con ello se puede ignorar otras opciones que tienen tiempo muy
bajos.

Ahora, en cuanto a los planes de ejecución, solo comentaré el de los cuatro
mejores tiempos:

Las sentencias 2 y 6 son diferentes entre si y diferente a la 7 y la 8, las
cuales si son iguales entre ellos (los planes), a la vez que el 6 si es
igual 5, aun cuando el 5 tuvo un resultado un poco menor pero que no es
despreciable.

El plan de jecución de las consultas 7 y 8 son iguales.

Ahora, lo que no tomé en cuenta para éste análisis fue los números
individuales de cada uno de los componentes del plan de ejecución, jejeje,
tengo que trabajar mis disculpas.

No se si esto sea suficiente con los resultados obtenidos hasta ahora.

Saludos.

P.D. El script de la última prueba es la siguiente:

==> --Número de registros 2.342.560
declare @inicio datetime,
@fin datetime,
@dif int



DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id = o.id
WHERE o.name = 'aaa' and i.indid = 1
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '1) SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id
= o.id WHERE o.name = ''aaa'' and i.indid = 1 (' + cast( @dif as varchar ) +
') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID('aaa') AND indid = 1
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '2) SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID(''aaa'') AND
indid = 1 (' + cast( @dif as varchar ) + ') milisegundos'


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select count(*) from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '3) select count(*) from aaa (' + 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 '4) select 1 from aaa (' + 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 '5) select top 1 * from aaa (' + 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 '6) select top 1 1 from aaa (' + 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 '7) if exists(select * from aaa ) print ''tiene filas'' else print
''NO tiene filas'' (' + 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 '8) if exists(select 1 from aaa ) print ''tiene filas'' else print
''NO tiene filas'' (' + 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 '9) if (select count(*) from aaa ) > 0 print ''tiene filas'' else
print ''NO tiene filas'' (' + cast( @dif as varchar ) + ') milisegundos'
==>

"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 )
Respuesta Responder a este mensaje
#25 Alejandro Mesa
30/10/2007 - 16:56 | Informe spam
Se me olvido decir que has hecho un buen trabajo. Lo mismo podria haberlo
hecho "Peni", antes de hacer la pregunta en el grupo.

Saludos,
Alejandro Mesa

P.S. Puedes postear tu nombre o prefieres el anonimato?

"jeastman - Hotmail" wrote:

Dosculpen...


En la primera presentación de resultados y en la anterior respuesta a
Alejandro obvié algunos resultados, los anoto a continuación:

Los dos primeros son los sugerido por Ruben, los demás fueron la sugerencia
de Alejandro.

1) SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id = o.id
WHERE o.name = 'aaa' and i.indid = 1 (16) milisegundos
2) SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID('aaa') AND indid = 1
(0) milisegundos
3) select count(*) from aaa (10940) milisegundos
4) select 1 from aaa (11860) milisegundos
5) select top 1 * from aaa (80) milisegundos
6) select top 1 1 from aaa (0) milisegundos
7) if exists(select * from aaa ) print 'tiene filas' else print 'NO tiene
filas' (0) milisegundos
8) if exists(select 1 from aaa ) print 'tiene filas' else print 'NO tiene
filas' (0) milisegundos
9) if (select count(*) from aaa ) > 0 print 'tiene filas' else print 'NO
tiene filas' (11623) milisegundos

La corrida de evaluación de tiempo fue ejecutada sin visualizar el plan de
ejecución para no tomar en cuenta los tiempos requerido para ello.

Como podemos observar las sentencias ( 2, 6, 7, 8 ) obtuvieron los mejores
tiempo, no con ello se puede ignorar otras opciones que tienen tiempo muy
bajos.

Ahora, en cuanto a los planes de ejecución, solo comentaré el de los cuatro
mejores tiempos:

Las sentencias 2 y 6 son diferentes entre si y diferente a la 7 y la 8, las
cuales si son iguales entre ellos (los planes), a la vez que el 6 si es
igual 5, aun cuando el 5 tuvo un resultado un poco menor pero que no es
despreciable.

El plan de jecución de las consultas 7 y 8 son iguales.

Ahora, lo que no tomé en cuenta para éste análisis fue los números
individuales de cada uno de los componentes del plan de ejecución, jejeje,
tengo que trabajar mis disculpas.

No se si esto sea suficiente con los resultados obtenidos hasta ahora.

Saludos.

P.D. El script de la última prueba es la siguiente:

==> --Número de registros 2.342.560
declare @inicio datetime,
@fin datetime,
@dif int



DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id = o.id
WHERE o.name = 'aaa' and i.indid = 1
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '1) SELECT i.rowcnt FROM sysindexes i INNER JOIN sysobjects o ON i.id
= o.id WHERE o.name = ''aaa'' and i.indid = 1 (' + cast( @dif as varchar ) +
') milisegundos'

DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID('aaa') AND indid = 1
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '2) SELECT rowcnt FROM sysindexes WHERE id = OBJECT_ID(''aaa'') AND
indid = 1 (' + cast( @dif as varchar ) + ') milisegundos'


DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
set @inicio = getdate()
select count(*) from aaa
set @fin = getdate()
set @dif = datediff( ms, @inicio, @fin )
print '3) select count(*) from aaa (' + 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 '4) select 1 from aaa (' + 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 '5) select top 1 * from aaa (' + 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 '6) select top 1 1 from aaa (' + 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 '7) if exists(select * from aaa ) print ''tiene filas'' else print
''NO tiene filas'' (' + 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 '8) if exists(select 1 from aaa ) print ''tiene filas'' else print
''NO tiene filas'' (' + 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 '9) if (select count(*) from aaa ) > 0 print ''tiene filas'' else
print ''NO tiene filas'' (' + cast( @dif as varchar ) + ') milisegundos'
==>

"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 )
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida