Consulta muy lenta

25/04/2005 - 19:27 por manolo | Informe spam
Hola,

Tengo una consulta que se ejecuta muy lenta.
Mi idea es unir 6 tablas y este es más o menos el resumen:

Albaranes.IdAlbaran, Albaranes.idCliente
Facturas.IdFactura, Facturas.idCliente
Tickets.idTicket, Tickets.idCliente
Detalles.idAlbaran, Detalles.idFactura, Detalles.idTicket,
Detalles.idArticulo
Articulos.idArticulo
Clientes.idCliente

Pues bien, quiero hacer una vista que muestre todos los movimientos de
artículos según el detalle.
Un detalle puede formar parte de un albarán, de un albarán y una
factura, de una factura, de un ticket y una factura o de un ticket, por lo
cual hago las uniones con right join.
Para devolver el cliente, utilizo la función coalesce, que devuelve el
primer valor no nulo de una lista de valores. Pues es en esta línea donde se
relentiza mucho la consulta, tarda de 5 a 10 minutos con unos 20000
registros y si le quito la línea es casi instantánea.
La línea en cuestión es:

from ...
inner join Clientes on Clientes.idCliente = coalesce(Albaranes.idCliente,
Facturas.idCliente, Tickets.idCliente)

¿Existe otra ffunción o existe otro modo de solucionar la velocidad?

Muchas gracias, perdón por el sermón y un saludo.

P.D. para facilitar la lectura, he omitido algunas tablas, he cambiado los
nombres de las tablas y de los campos. la consulta completa es:

select Articulos.Codigo as codArticulo,
rtrim(Articulos.Descripcion + ' ' + Tallas.Descripcion + ' ' +
Colores.Descripcion) as descripcion,
Articulos.cInterno,
DetallesAlbaranesVentas.Cantidad,
DetallesAlbaranesVentas.Precio,
DetallesAlbaranesVentas.Tipo,
DetallesAlbaranesVentas.Ejercicio,
coalesce(AlbaranesVentas.Cliente, FacturasVentas.Cliente,
TicketsVentas.Cliente) as Cliente,
coalesce(AlbaranesVentas.FechaAlbaran, FacturasVentas.FechaFactura,
TicketsVentas.FechaTicket) as Fecha,
convert(nvarchar(16), AlbaranesVentas.numAlbaran) as numAlbaran,
FacturasVentas.numFactura,
TicketsVentas.NumTicket,
Clientes.RazonSocial
from Articulos left join Tallas on articulos.talla = tallas.Codigo left join
colores on articulos.color = colores.codigo
inner join DetallesAlbaranesVentas on Articulos.Codigo =
DetallesAlbaranesVentas.codArticulo
left join AlbaranesVentas on DetallesAlbaranesVentas.numAlbaran =
AlbaranesVentas.numAlbaran and DetallesAlbaranesVentas.Ejercicio =
AlbaranesVentas.Ejercicio and DetallesAlbaranesVentas.Serie =
AlbaranesVentas.Serie
left join FacturasVentas on DetallesAlbaranesVentas.numFactura =
FacturasVentas.numFactura and DetallesAlbaranesVentas.EjercicioFacturas =
FacturasVentas.Ejercicio and DetallesAlbaranesVentas.Serie =
FacturasVentas.Serie
left join TicketsVentas on DetallesAlbaranesVentas.numTicket =
TicketsVentas.numTicket and DetallesAlbaranesVentas.EjercicioFacturas =
TicketsVentas.Ejercicio and DetallesAlbaranesVentas.Serie =
TicketsVentas.Serie
inner join Clientes on Clientes.Codigo = coalesce(AlbaranesVentas.Cliente,
FacturasVentas.Cliente, TicketsVentas.Cliente)

Preguntas similare

Leer las respuestas

#1 qwalgrande
24/04/2005 - 22:54 | Informe spam
Hola.

A modo de sugerencia, si te fijas, sólo hay un campo que necesites de la
tablas Clientes, el campo RazónSocial. Bien, crea una función que te lo
devuelva, pasándole código, que obtendrías en tu consulta del coalesce de
AlbaranesVentas.Cliente, FacturasVentas.Cliente y TicketsVentas.Cliente. Así
ya no tendrías que incluir la tabla Clientes en la consulta. Suponiendo que
el campo RazonSocial es un nvarchar(255) y el campo Codigo un int, sería:

create function Cliente_RazonSocial(@pCodigo int) returns nvarchar(255)
begin
declare @ret nvarchar(255)

select @ret = RazonSocial from Clientes where Codigo = @pCodigo

return @ret
end

Y tu consulta quedaría:

select Articulos.Codigo as codArticulo,
...
dbo.Cliente_RazonSocial(coalesce(AlbaranesVentas.Cliente,
FacturasVentas.Cliente, TicketsVentas.Cliente) as RazonSocial

from Articulos left join Tallas on articulos.talla = tallas.Codigo left join
colores on articulos.color = colores.codigo
inner join DetallesAlbaranesVentas on Articulos.Codigo DetallesAlbaranesVentas.codArticulo
left join AlbaranesVentas on DetallesAlbaranesVentas.numAlbaran AlbaranesVentas.numAlbaran and DetallesAlbaranesVentas.Ejercicio AlbaranesVentas.Ejercicio and DetallesAlbaranesVentas.Serie AlbaranesVentas.Serie
left join FacturasVentas on DetallesAlbaranesVentas.numFactura FacturasVentas.numFactura and DetallesAlbaranesVentas.EjercicioFacturas FacturasVentas.Ejercicio and DetallesAlbaranesVentas.Serie FacturasVentas.Serie
left join TicketsVentas on DetallesAlbaranesVentas.numTicket TicketsVentas.numTicket and DetallesAlbaranesVentas.EjercicioFacturas TicketsVentas.Ejercicio and DetallesAlbaranesVentas.Serie TicketsVentas.Serie

qwalgrande


"manolo" escribió en el mensaje
news:
Hola,

Tengo una consulta que se ejecuta muy lenta.
Mi idea es unir 6 tablas y este es más o menos el resumen:

Albaranes.IdAlbaran, Albaranes.idCliente
Facturas.IdFactura, Facturas.idCliente
Tickets.idTicket, Tickets.idCliente
Detalles.idAlbaran, Detalles.idFactura, Detalles.idTicket,
Detalles.idArticulo
Articulos.idArticulo
Clientes.idCliente

Pues bien, quiero hacer una vista que muestre todos los movimientos de
artículos según el detalle.
Un detalle puede formar parte de un albarán, de un albarán y una
factura, de una factura, de un ticket y una factura o de un ticket, por lo
cual hago las uniones con right join.
Para devolver el cliente, utilizo la función coalesce, que devuelve el
primer valor no nulo de una lista de valores. Pues es en esta línea donde
se relentiza mucho la consulta, tarda de 5 a 10 minutos con unos 20000
registros y si le quito la línea es casi instantánea.
La línea en cuestión es:

from ...
inner join Clientes on Clientes.idCliente = coalesce(Albaranes.idCliente,
Facturas.idCliente, Tickets.idCliente)

¿Existe otra ffunción o existe otro modo de solucionar la velocidad?

Muchas gracias, perdón por el sermón y un saludo.

P.D. para facilitar la lectura, he omitido algunas tablas, he cambiado los
nombres de las tablas y de los campos. la consulta completa es:

select Articulos.Codigo as codArticulo,
rtrim(Articulos.Descripcion + ' ' + Tallas.Descripcion + ' ' +
Colores.Descripcion) as descripcion,
Articulos.cInterno,
DetallesAlbaranesVentas.Cantidad,
DetallesAlbaranesVentas.Precio,
DetallesAlbaranesVentas.Tipo,
DetallesAlbaranesVentas.Ejercicio,
coalesce(AlbaranesVentas.Cliente, FacturasVentas.Cliente,
TicketsVentas.Cliente) as Cliente,
coalesce(AlbaranesVentas.FechaAlbaran, FacturasVentas.FechaFactura,
TicketsVentas.FechaTicket) as Fecha,
convert(nvarchar(16), AlbaranesVentas.numAlbaran) as numAlbaran,
FacturasVentas.numFactura,
TicketsVentas.NumTicket,
Clientes.RazonSocial
from Articulos left join Tallas on articulos.talla = tallas.Codigo left
join colores on articulos.color = colores.codigo
inner join DetallesAlbaranesVentas on Articulos.Codigo =
DetallesAlbaranesVentas.codArticulo
left join AlbaranesVentas on DetallesAlbaranesVentas.numAlbaran =
AlbaranesVentas.numAlbaran and DetallesAlbaranesVentas.Ejercicio =
AlbaranesVentas.Ejercicio and DetallesAlbaranesVentas.Serie =
AlbaranesVentas.Serie
left join FacturasVentas on DetallesAlbaranesVentas.numFactura =
FacturasVentas.numFactura and DetallesAlbaranesVentas.EjercicioFacturas =
FacturasVentas.Ejercicio and DetallesAlbaranesVentas.Serie =
FacturasVentas.Serie
left join TicketsVentas on DetallesAlbaranesVentas.numTicket =
TicketsVentas.numTicket and DetallesAlbaranesVentas.EjercicioFacturas =
TicketsVentas.Ejercicio and DetallesAlbaranesVentas.Serie =
TicketsVentas.Serie
inner join Clientes on Clientes.Codigo = coalesce(AlbaranesVentas.Cliente,
FacturasVentas.Cliente, TicketsVentas.Cliente)


Respuesta Responder a este mensaje
#2 Jose Mariano Alvarez
25/04/2005 - 19:40 | Informe spam
Sugiero si te sirve que pruebes con UNION en lugar de los LEFT JOIN.

Select 1
UNION
Select 2
UNION
Select 3

Saludos
Jose Mariano
Respuesta Responder a este mensaje
#3 Jose Mariano Alvarez
25/04/2005 - 19:40 | Informe spam
Sugiero si te sirve que pruebes con UNION en lugar de los LEFT JOIN.

Select 1
UNION
Select 2
UNION
Select 3

Saludos
Jose Mariano Alvarez
Respuesta Responder a este mensaje
#4 manolo
25/04/2005 - 19:53 | Informe spam
Hola Jose Mariano,

El caso es que de esta forma me daría datos duplicados.

Cuando creo un albarán, creo un registro en la tabla Albaranes y un
registro por artículo del albarán en la tabla detalles.
Cuando creo una factura de este albarán, lo único que hago en la tabla
detalles es ponerle el número de factura al campo idFactura.
De la misma forma, puedo crear una factura que no proceda de un albarán,
por lo cual el campo idAlbaran puede ser nulo.
Es por esto por lo que no puedo hacer una unión. los campos resumidos
que me debe devolver la consulta son:

Artículo, Cliente, nº Factura, nº Albarán, nº Ticket, Fecha factura,
Fecha albarán, Fecha Ticket, Cantidad, Precio.

De este modo de un vistazo podría ver en que fechas, documentos y precio
se vendió un artículo, haciendo sum, la cantidad que se ha vendido, uniendo
esta consulta con un union a otra consulta de compras ver el stock actual de
los artículos, etc...

Gracias y un saludo.

"Jose Mariano Alvarez" escribió en el mensaje
news:
Sugiero si te sirve que pruebes con UNION en lugar de los LEFT JOIN.

Select 1
UNION
Select 2
UNION
Select 3

Saludos
Jose Mariano

Respuesta Responder a este mensaje
#5 Alejandro Mesa
25/04/2005 - 20:43 | Informe spam
Manolo,

Crea tres sentencias. Una para sacar la informacion desde AlbaranesVentas,
para aquellos que no tengan factura o ticket asociados. Una segunda que saca
la informacion desde FacturasVentas, pero solo aquellas facturas que no
tengan filas asociadas en AlbaranesVentas y TicketsVentas. Una tercera para
seleccionar info desde TicketsVentas, solo aquellas filas que no tengan
asociadas una fila en AlbaranesVentas y FacturasVentas. entonces puedes hacer
la union de las tres.


AMB

"manolo" wrote:

Hola Jose Mariano,

El caso es que de esta forma me daría datos duplicados.

Cuando creo un albarán, creo un registro en la tabla Albaranes y un
registro por artículo del albarán en la tabla detalles.
Cuando creo una factura de este albarán, lo único que hago en la tabla
detalles es ponerle el número de factura al campo idFactura.
De la misma forma, puedo crear una factura que no proceda de un albarán,
por lo cual el campo idAlbaran puede ser nulo.
Es por esto por lo que no puedo hacer una unión. los campos resumidos
que me debe devolver la consulta son:

Artículo, Cliente, nº Factura, nº Albarán, nº Ticket, Fecha factura,
Fecha albarán, Fecha Ticket, Cantidad, Precio.

De este modo de un vistazo podría ver en que fechas, documentos y precio
se vendió un artículo, haciendo sum, la cantidad que se ha vendido, uniendo
esta consulta con un union a otra consulta de compras ver el stock actual de
los artículos, etc...

Gracias y un saludo.

"Jose Mariano Alvarez" escribió en el mensaje
news:
> Sugiero si te sirve que pruebes con UNION en lugar de los LEFT JOIN.
>
> Select 1
> UNION
> Select 2
> UNION
> Select 3
>
> Saludos
> Jose Mariano
>



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