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)
 

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)


Preguntas similares