vista unificada de varias tablas,problema con plan de ejecucion

15/06/2006 - 23:22 por Silverius | Informe spam
Hola a todos,

Tengo un conjunto de operaciones particionado por meses en varias tablas

create table OperacionesEnero(id int,codigo int,fecha datetime)
create table OperacionesFebrero(id int,codigo int,fecha datetime)
asi hasta varios meses (cada tabla tiene una constraint en "fecha" para
que los datos no puedan estar fuera de ese mes)

Y una vista que unifica estas tablas
create view VistaUnificada
as
select id,codigo,fecha from OperacionesEnero union all
select id,codigo,fecha from OperacionesEnero..

Se que no es el mejor diseño, pero es como esta y cambiarlo nos es ahora
mismo imposible.

El caso es que cuando ejecuto una consulta, por ejemplo
select * from VistaUnificada where fecha='20060615',el plan de consulta
muestra que solo se busca en la tabla de Junio.Pero cuendo hago un
procedimiento como:select * from VistaUnificada where fecha=@fecha y lo
ejecuto, el plan de consulta muestra que se busca en todas las tablas.En la
practica,con el parametro tarda tambien muchisimo mas.
Entiendo que esto sera debido a que el servidor tiene que crear un plan de
ejecucion generico, ya que no sabe que contendra el parametro.


Mi pregunta es,hay alguna manera de salvar esto y hacer que solo busque en
la tabla necesaria? el procedimiento no se usa demasiado, asi que no me
importa que se recompile muchas veces.Yo he pensado en sql dinamico,pero me
parece un poco chapucero.
Otra pregunta:Las tablas de operaciones mensuales son muy utilizadas en mi
sistema.Cuando ejecuto una select normal sobre la vista,si la consulta es
pesada se generan un monton de bloqueos en la bbdd.Sabeis a que puede ser
debido?

Gracias por todo y perdonar que no ponga los scripts pero no tengo acceso
ahora mismo al servidor.Espero haber sido claro, cualquier ayuda la
agradecere.

Un saludo.

Preguntas similare

Leer las respuestas

#1 Ele
16/06/2006 - 01:34 | Informe spam
hola sobre los bloqueos checa esta instruccion SET TRANSACTION ISOLATION
LEVEL
acerca de la vista pues es tema de indices en la vista. Pero la opcion que
yo haria asi como esta el diseño es que solo consultaras un mes y si hacerlo
dinamico
Por ejemplo para cada mes agregar codigo asi
If DatePart(mm,@Fecha) = 1
Begin
select * from enero where Fecha = @Fecha
End
la desventaja es que no funciona con rango de fechas

"Silverius" escribió en el mensaje
news:
Hola a todos,

Tengo un conjunto de operaciones particionado por meses en varias tablas

create table OperacionesEnero(id int,codigo int,fecha datetime)
create table OperacionesFebrero(id int,codigo int,fecha datetime)
asi hasta varios meses (cada tabla tiene una constraint en "fecha"
para
que los datos no puedan estar fuera de ese mes)

Y una vista que unifica estas tablas
create view VistaUnificada
as
select id,codigo,fecha from OperacionesEnero union all
select id,codigo,fecha from OperacionesEnero..

Se que no es el mejor diseño, pero es como esta y cambiarlo nos es ahora
mismo imposible.

El caso es que cuando ejecuto una consulta, por ejemplo
select * from VistaUnificada where fecha='20060615',el plan de consulta
muestra que solo se busca en la tabla de Junio.Pero cuendo hago un
procedimiento como:select * from VistaUnificada where fecha=@fecha y lo
ejecuto, el plan de consulta muestra que se busca en todas las tablas.En
la
practica,con el parametro tarda tambien muchisimo mas.
Entiendo que esto sera debido a que el servidor tiene que crear un plan de
ejecucion generico, ya que no sabe que contendra el parametro.


Mi pregunta es,hay alguna manera de salvar esto y hacer que solo busque en
la tabla necesaria? el procedimiento no se usa demasiado, asi que no me
importa que se recompile muchas veces.Yo he pensado en sql dinamico,pero
me
parece un poco chapucero.
Otra pregunta:Las tablas de operaciones mensuales son muy utilizadas en mi
sistema.Cuando ejecuto una select normal sobre la vista,si la consulta es
pesada se generan un monton de bloqueos en la bbdd.Sabeis a que puede ser
debido?

Gracias por todo y perdonar que no ponga los scripts pero no tengo acceso
ahora mismo al servidor.Espero haber sido claro, cualquier ayuda la
agradecere.

Un saludo.


Respuesta Responder a este mensaje
#2 Silverius
16/06/2006 - 13:29 | Informe spam
no tengo puesto ningun nivel de transaccion
La vista la hago justamente para no hacer lo que indicas,ya que el sql
server penaliza mucho esto en cuanto a rendimiento.Ademas de que si
quiero consultar un rango de varias tablas debo concatenar etc.

Gracias de todos modos.


Ele ha escrito:

hola sobre los bloqueos checa esta instruccion SET TRANSACTION ISOLATION
LEVEL
acerca de la vista pues es tema de indices en la vista. Pero la opcion que
yo haria asi como esta el diseño es que solo consultaras un mes y si hacerlo
dinamico
Por ejemplo para cada mes agregar codigo asi
If DatePart(mm,@Fecha) = 1
Begin
select * from enero where Fecha = @Fecha
End
la desventaja es que no funciona con rango de fechas

"Silverius" escribió en el mensaje
news:
> Hola a todos,
>
> Tengo un conjunto de operaciones particionado por meses en varias tablas
>
> create table OperacionesEnero(id int,codigo int,fecha datetime)
> create table OperacionesFebrero(id int,codigo int,fecha datetime)
> asi hasta varios meses (cada tabla tiene una constraint en "fecha"
> para
> que los datos no puedan estar fuera de ese mes)
>
> Y una vista que unifica estas tablas
> create view VistaUnificada
> as
> select id,codigo,fecha from OperacionesEnero union all
> select id,codigo,fecha from OperacionesEnero..
>
> Se que no es el mejor diseño, pero es como esta y cambiarlo nos es ahora
> mismo imposible.
>
> El caso es que cuando ejecuto una consulta, por ejemplo
> select * from VistaUnificada where fecha='20060615',el plan de consulta
> muestra que solo se busca en la tabla de Junio.Pero cuendo hago un
> procedimiento como:select * from VistaUnificada where fecha=@fecha y lo
> ejecuto, el plan de consulta muestra que se busca en todas las tablas.En
> la
> practica,con el parametro tarda tambien muchisimo mas.
> Entiendo que esto sera debido a que el servidor tiene que crear un plan de
> ejecucion generico, ya que no sabe que contendra el parametro.
>
>
> Mi pregunta es,hay alguna manera de salvar esto y hacer que solo busque en
> la tabla necesaria? el procedimiento no se usa demasiado, asi que no me
> importa que se recompile muchas veces.Yo he pensado en sql dinamico,pero
> me
> parece un poco chapucero.
> Otra pregunta:Las tablas de operaciones mensuales son muy utilizadas en mi
> sistema.Cuando ejecuto una select normal sobre la vista,si la consulta es
> pesada se generan un monton de bloqueos en la bbdd.Sabeis a que puede ser
> debido?
>
> Gracias por todo y perdonar que no ponga los scripts pero no tengo acceso
> ahora mismo al servidor.Espero haber sido claro, cualquier ayuda la
> agradecere.
>
> Un saludo.
>
>
Respuesta Responder a este mensaje
#3 qwalgrande
20/06/2006 - 20:50 | Informe spam
Hola.

El problema que tienes es que el plan de ejecución del procedimiento
almacenado queda en caché, y lo que queda en caché no lleva una fecha fija,
la fecha puede tener cualquier valor. Sin embargo, cuando se lo pasas
directamente, el plan de ejecución se crea para tu consulta, con un valor
fijo, no tiene que pensar en almacenarlo y va directo a la tabla que le
atañe.

Tu ejemplo es uno de los pocos casos en los que no te conviene utilizar un
procedimiento almacenado. Lo que yo haría sería crear la vista como vista
indexada, en el que la fecha sea el primer campo del índice único que se
requiere para las vistas indexadas. Hay otras soluciones a lo que comentas.

Alberto López Grande (qwalgrande)


"Silverius" escribió en el mensaje
news:
no tengo puesto ningun nivel de transaccion
La vista la hago justamente para no hacer lo que indicas,ya que el sql
server penaliza mucho esto en cuanto a rendimiento.Ademas de que si
quiero consultar un rango de varias tablas debo concatenar etc.

Gracias de todos modos.


Ele ha escrito:

hola sobre los bloqueos checa esta instruccion SET TRANSACTION ISOLATION
LEVEL
acerca de la vista pues es tema de indices en la vista. Pero la opcion que
yo haria asi como esta el diseño es que solo consultaras un mes y si
hacerlo
dinamico
Por ejemplo para cada mes agregar codigo asi
If DatePart(mm,@Fecha) = 1
Begin
select * from enero where Fecha = @Fecha
End
la desventaja es que no funciona con rango de fechas

"Silverius" escribió en el mensaje
news:
> Hola a todos,
>
> Tengo un conjunto de operaciones particionado por meses en varias tablas
>
> create table OperacionesEnero(id int,codigo int,fecha datetime)
> create table OperacionesFebrero(id int,codigo int,fecha datetime)
> asi hasta varios meses (cada tabla tiene una constraint en "fecha"
> para
> que los datos no puedan estar fuera de ese mes)
>
> Y una vista que unifica estas tablas
> create view VistaUnificada
> as
> select id,codigo,fecha from OperacionesEnero union all
> select id,codigo,fecha from OperacionesEnero..
>
> Se que no es el mejor diseño, pero es como esta y cambiarlo nos es ahora
> mismo imposible.
>
> El caso es que cuando ejecuto una consulta, por ejemplo
> select * from VistaUnificada where fecha='20060615',el plan de consulta
> muestra que solo se busca en la tabla de Junio.Pero cuendo hago un
> procedimiento como:select * from VistaUnificada where fecha=@fecha y lo
> ejecuto, el plan de consulta muestra que se busca en todas las tablas.En
> la
> practica,con el parametro tarda tambien muchisimo mas.
> Entiendo que esto sera debido a que el servidor tiene que crear un plan
> de
> ejecucion generico, ya que no sabe que contendra el parametro.
>
>
> Mi pregunta es,hay alguna manera de salvar esto y hacer que solo busque
> en
> la tabla necesaria? el procedimiento no se usa demasiado, asi que no me
> importa que se recompile muchas veces.Yo he pensado en sql dinamico,pero
> me
> parece un poco chapucero.
> Otra pregunta:Las tablas de operaciones mensuales son muy utilizadas en
> mi
> sistema.Cuando ejecuto una select normal sobre la vista,si la consulta
> es
> pesada se generan un monton de bloqueos en la bbdd.Sabeis a que puede
> ser
> debido?
>
> Gracias por todo y perdonar que no ponga los scripts pero no tengo
> acceso
> ahora mismo al servidor.Espero haber sido claro, cualquier ayuda la
> agradecere.
>
> Un saludo.
>
>
Respuesta Responder a este mensaje
#4 Miguel Egea
21/06/2006 - 08:28 | Informe spam
Casualidades de la vida, justo hoy estoy con Alberto (lo digo para el resto
del grupo :) y pretendo demostrar que a pesar de que el plan de ejecución
luce genérico, sigue siendo en estos casos útil usar particiones, os pongo
un ejemplo, veréis que los execution plan son idénticos, sin embargo las
restricciones check permiten que dependiendo del valor real realmente no se
ejecute el scan que está luciendo en el plan de ejecución, así que set
statistics io on nos está revelendo la grandeza del equipo del Query
Optimizer de SQL Server, (disculpad que ponga las letras grandes, es que
tengo el management studio en formato grande para que los alumnos puedan ver
bien el código).

drop table sample2003

drop table sample2004

drop table sample2005

create table sample2003 (id int not null ,

fecha datetime check (fecha between '19000101' and '20031231'),

foo char(10) ,

constraint pk_sample2003 primary key (fecha,id))

go

create table sample2004 (id int not null ,

fecha datetime check (fecha between '20040101' and '20051231'),

foo char(10) ,

constraint pk_sample2004 primary key (fecha,id))

go

create table sample2005 (id int not null ,

fecha datetime check (fecha between '20060101' and '20201201'),

foo char(10) ,

constraint pk_sample2005 primary key (fecha,id))

go

create view sample as

select * from sample2003

union all

select * from sample2004

union all

select * from sample2005

go


insert into sample (id,fecha,foo)

select salesorderid,orderdate,salesordernumber From
Adventureworks.sales.salesorderheader

go

set statistics io on

go

select * from sample where fecha>='20031201'

go

declare @fecha datetime

set @fecha='20050101'

select * from sample where fecha>=@fecha

go

declare @fecha datetime

set @fecha='20020101'

select * from sample where fecha>=@fecha


"qwalgrande" escribió en el mensaje
news:%
Hola.

El problema que tienes es que el plan de ejecución del procedimiento
almacenado queda en caché, y lo que queda en caché no lleva una fecha
fija, la fecha puede tener cualquier valor. Sin embargo, cuando se lo
pasas directamente, el plan de ejecución se crea para tu consulta, con un
valor fijo, no tiene que pensar en almacenarlo y va directo a la tabla que
le atañe.

Tu ejemplo es uno de los pocos casos en los que no te conviene utilizar un
procedimiento almacenado. Lo que yo haría sería crear la vista como vista
indexada, en el que la fecha sea el primer campo del índice único que se
requiere para las vistas indexadas. Hay otras soluciones a lo que
comentas.

Alberto López Grande (qwalgrande)


"Silverius" escribió en el mensaje
news:
no tengo puesto ningun nivel de transaccion
La vista la hago justamente para no hacer lo que indicas,ya que el sql
server penaliza mucho esto en cuanto a rendimiento.Ademas de que si
quiero consultar un rango de varias tablas debo concatenar etc.

Gracias de todos modos.


Ele ha escrito:

hola sobre los bloqueos checa esta instruccion SET TRANSACTION ISOLATION
LEVEL
acerca de la vista pues es tema de indices en la vista. Pero la opcion
que
yo haria asi como esta el diseño es que solo consultaras un mes y si
hacerlo
dinamico
Por ejemplo para cada mes agregar codigo asi
If DatePart(mm,@Fecha) = 1
Begin
select * from enero where Fecha = @Fecha
End
la desventaja es que no funciona con rango de fechas

"Silverius" escribió en el mensaje
news:
> Hola a todos,
>
> Tengo un conjunto de operaciones particionado por meses en varias
> tablas
>
> create table OperacionesEnero(id int,codigo int,fecha datetime)
> create table OperacionesFebrero(id int,codigo int,fecha datetime)
> asi hasta varios meses (cada tabla tiene una constraint en "fecha"
> para
> que los datos no puedan estar fuera de ese mes)
>
> Y una vista que unifica estas tablas
> create view VistaUnificada
> as
> select id,codigo,fecha from OperacionesEnero union all
> select id,codigo,fecha from OperacionesEnero..
>
> Se que no es el mejor diseño, pero es como esta y cambiarlo nos es
> ahora
> mismo imposible.
>
> El caso es que cuando ejecuto una consulta, por ejemplo
> select * from VistaUnificada where fecha='20060615',el plan de consulta
> muestra que solo se busca en la tabla de Junio.Pero cuendo hago un
> procedimiento como:select * from VistaUnificada where fecha=@fecha y lo
> ejecuto, el plan de consulta muestra que se busca en todas las
> tablas.En
> la
> practica,con el parametro tarda tambien muchisimo mas.
> Entiendo que esto sera debido a que el servidor tiene que crear un plan
> de
> ejecucion generico, ya que no sabe que contendra el parametro.
>
>
> Mi pregunta es,hay alguna manera de salvar esto y hacer que solo busque
> en
> la tabla necesaria? el procedimiento no se usa demasiado, asi que no me
> importa que se recompile muchas veces.Yo he pensado en sql
> dinamico,pero
> me
> parece un poco chapucero.
> Otra pregunta:Las tablas de operaciones mensuales son muy utilizadas en
> mi
> sistema.Cuando ejecuto una select normal sobre la vista,si la consulta
> es
> pesada se generan un monton de bloqueos en la bbdd.Sabeis a que puede
> ser
> debido?
>
> Gracias por todo y perdonar que no ponga los scripts pero no tengo
> acceso
> ahora mismo al servidor.Espero haber sido claro, cualquier ayuda la
> agradecere.
>
> Un saludo.
>
>




Respuesta Responder a este mensaje
#5 Miguel Egea
26/06/2006 - 23:41 | Informe spam
Esto lo contesté hace una semana, pero no salió...

Casualidades de la vida, justo hoy estoy con Alberto (lo digo para el resto
del grupo :) y pretendo demostrar que a pesar de que el plan de ejecución
luce genérico, sigue siendo en estos casos útil usar particiones, os pongo
un ejemplo, veréis que los execution plan son idénticos, sin embargo las
restricciones check permiten que dependiendo del valor real realmente no se
ejecute el scan que está luciendo en el plan de ejecución, así que set
statistics io on nos está revelendo la grandeza del equipo del Query
Optimizer de SQL Server, (disculpad que ponga las letras grandes, es que
tengo el management studio en formato grande para que los alumnos puedan ver
bien el código).

drop table sample2003

drop table sample2004

drop table sample2005

create table sample2003 (id int not null ,

fecha datetime check (fecha between '19000101' and '20031231'),

foo char(10) ,

constraint pk_sample2003 primary key (fecha,id))

go

create table sample2004 (id int not null ,

fecha datetime check (fecha between '20040101' and '20051231'),

foo char(10) ,

constraint pk_sample2004 primary key (fecha,id))

go

create table sample2005 (id int not null ,

fecha datetime check (fecha between '20060101' and '20201201'),

foo char(10) ,

constraint pk_sample2005 primary key (fecha,id))

go

create view sample as

select * from sample2003

union all

select * from sample2004

union all

select * from sample2005

go


insert into sample (id,fecha,foo)

select salesorderid,orderdate,salesordernumber From
Adventureworks.sales.salesorderheader

go

set statistics io on

go

select * from sample where fecha>='20031201'

go

declare @fecha datetime

set @fecha='20050101'

select * from sample where fecha>=@fecha

go

declare @fecha datetime

set @fecha='20020101'

select * from sample where fecha>=@fecha

Si te fijas, aunque el plan luce horroroso, las lecturas no son lo que
pudiera parecer..

Saludos



"qwalgrande" escribió en el mensaje
news:%
Hola.

El problema que tienes es que el plan de ejecución del procedimiento
almacenado queda en caché, y lo que queda en caché no lleva una fecha
fija, la fecha puede tener cualquier valor. Sin embargo, cuando se lo
pasas directamente, el plan de ejecución se crea para tu consulta, con un
valor fijo, no tiene que pensar en almacenarlo y va directo a la tabla que
le atañe.

Tu ejemplo es uno de los pocos casos en los que no te conviene utilizar un
procedimiento almacenado. Lo que yo haría sería crear la vista como vista
indexada, en el que la fecha sea el primer campo del índice único que se
requiere para las vistas indexadas. Hay otras soluciones a lo que
comentas.

Alberto López Grande (qwalgrande)


"Silverius" escribió en el mensaje
news:
no tengo puesto ningun nivel de transaccion
La vista la hago justamente para no hacer lo que indicas,ya que el sql
server penaliza mucho esto en cuanto a rendimiento.Ademas de que si
quiero consultar un rango de varias tablas debo concatenar etc.

Gracias de todos modos.


Ele ha escrito:

hola sobre los bloqueos checa esta instruccion SET TRANSACTION ISOLATION
LEVEL
acerca de la vista pues es tema de indices en la vista. Pero la opcion
que
yo haria asi como esta el diseño es que solo consultaras un mes y si
hacerlo
dinamico
Por ejemplo para cada mes agregar codigo asi
If DatePart(mm,@Fecha) = 1
Begin
select * from enero where Fecha = @Fecha
End
la desventaja es que no funciona con rango de fechas

"Silverius" escribió en el mensaje
news:
> Hola a todos,
>
> Tengo un conjunto de operaciones particionado por meses en varias
> tablas
>
> create table OperacionesEnero(id int,codigo int,fecha datetime)
> create table OperacionesFebrero(id int,codigo int,fecha datetime)
> asi hasta varios meses (cada tabla tiene una constraint en "fecha"
> para
> que los datos no puedan estar fuera de ese mes)
>
> Y una vista que unifica estas tablas
> create view VistaUnificada
> as
> select id,codigo,fecha from OperacionesEnero union all
> select id,codigo,fecha from OperacionesEnero..
>
> Se que no es el mejor diseño, pero es como esta y cambiarlo nos es
> ahora
> mismo imposible.
>
> El caso es que cuando ejecuto una consulta, por ejemplo
> select * from VistaUnificada where fecha='20060615',el plan de consulta
> muestra que solo se busca en la tabla de Junio.Pero cuendo hago un
> procedimiento como:select * from VistaUnificada where fecha=@fecha y lo
> ejecuto, el plan de consulta muestra que se busca en todas las
> tablas.En
> la
> practica,con el parametro tarda tambien muchisimo mas.
> Entiendo que esto sera debido a que el servidor tiene que crear un plan
> de
> ejecucion generico, ya que no sabe que contendra el parametro.
>
>
> Mi pregunta es,hay alguna manera de salvar esto y hacer que solo busque
> en
> la tabla necesaria? el procedimiento no se usa demasiado, asi que no me
> importa que se recompile muchas veces.Yo he pensado en sql
> dinamico,pero
> me
> parece un poco chapucero.
> Otra pregunta:Las tablas de operaciones mensuales son muy utilizadas en
> mi
> sistema.Cuando ejecuto una select normal sobre la vista,si la consulta
> es
> pesada se generan un monton de bloqueos en la bbdd.Sabeis a que puede
> ser
> debido?
>
> Gracias por todo y perdonar que no ponga los scripts pero no tengo
> acceso
> ahora mismo al servidor.Espero haber sido claro, cualquier ayuda la
> agradecere.
>
> Un saludo.
>
>




email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida