Problema de rendimiento: Cambio en el plan de ejecucion

20/01/2006 - 12:58 por e.lorenzo | Informe spam
Saludos a todos y gracias anticipadas a quien pueda ayudarme.

Tenemos una aplicacion que lanza secuencias con la siguiente estructura:

CREATE TABLE TMPXXX

INSERT INTO TMPXXXX SELECT YYY FROM ZZZ

SELECT AAA FROM TMPXXX, WWWW

La cuestion es que si lo lanza todo seguido, los tiempos son muy buenos.
En algunos casos, se hace una comprobacion de si la tabla temporal que hay
que crear ya existe (de otra secuencia anterior) y, en estos casos, nos
encontramos con que cambia completamente el plan de ejecucion y la
consulta tarda mucho.

Investigando, probamos a poner un GO entre el INSERT y el SELECT y nos
vuelve a dar mal tiempo. Deducimos que al hacer el GO, SQL Server debia
actualizar las estadisticas de la tabla y modificaba el plan de ejecucion.

?Alguien puede decirme si esto tiene sentido? ?Alguna forma para
"eliminar" las estadisticas de la tabla y asi que coja el plan bueno?

Hemos hecho pruebas forzando el plan y se corrige, pero estropeamos otras
casuisticas.

Es SQL Server 2000.

Gracias y un saludo

Preguntas similare

Leer las respuestas

#1 Jose Mariano Alvarez
20/01/2006 - 15:06 | Informe spam
Podrias aclarar mas cosas.
No se entiende que quieres hacer.

Puedes eliminar las estadirsticas con drop statistics, puedes evitar que se
cree o se actualicen desde las opciones de configuracion de la base de datos,
puedes create indices explicitos a la tabla temporal, puedes usar variables
tabla, etc.

Ahora si todo se hace mediante table scan (segun dejan mostrar la queries)
no entiendo el sentido tu duda de cambiar el plan.

Ing. Jose Mariano Alvarez

J0sé P-u-n-t-0 Marian0 P-u-n-t-0 Álvarez ** gma1l P-u-n-t-0 c0n <-- M
(Saca guiones, blancos, acentos, ceros por o)

http://www.sqlgurus.org


"Quique" wrote:

Saludos a todos y gracias anticipadas a quien pueda ayudarme.

Tenemos una aplicacion que lanza secuencias con la siguiente estructura:

CREATE TABLE TMPXXX

INSERT INTO TMPXXXX SELECT YYY FROM ZZZ

SELECT AAA FROM TMPXXX, WWWW

La cuestion es que si lo lanza todo seguido, los tiempos son muy buenos.
En algunos casos, se hace una comprobacion de si la tabla temporal que hay
que crear ya existe (de otra secuencia anterior) y, en estos casos, nos
encontramos con que cambia completamente el plan de ejecucion y la
consulta tarda mucho.

Investigando, probamos a poner un GO entre el INSERT y el SELECT y nos
vuelve a dar mal tiempo. Deducimos que al hacer el GO, SQL Server debia
actualizar las estadisticas de la tabla y modificaba el plan de ejecucion.

?Alguien puede decirme si esto tiene sentido? ?Alguna forma para
"eliminar" las estadisticas de la tabla y asi que coja el plan bueno?

Hemos hecho pruebas forzando el plan y se corrige, pero estropeamos otras
casuisticas.

Es SQL Server 2000.

Gracias y un saludo



Respuesta Responder a este mensaje
#2 e.lorenzo
20/01/2006 - 15:25 | Informe spam
En vez de anidar una serie de sub-select, identificamos que era mucho mas
eficiente el crear una tabla temporal con los resultados de la sub-select
(sin borrarla despues, pues se podria reutilizar para otra secuencia).

De ahi, el primer CREATE y su posterior INSERT para rellenarla.

El SELECT cruza la tabla temporal con otro conjunto de tablas. La
estrategia es que haga un FULL a la tabla temporal y, para cada registro,
acceda a una de las tablas del conjunto por clave primaria (con NESTED
LOOP).

Si borro TODAS las estadisticas, estropeo todo. Necesitaria borrar solo
las estadisticas de la tabla temporal (la base de datos tiene
actualizacion automatica de las estadisticas y no querriamos cambiarlo).

?Se puede borrar las estadisticas de solo una tabla?

Gracias

Jose Mariano Alvarez wrote:

Podrias aclarar mas cosas.
No se entiende que quieres hacer.

Puedes eliminar las estadirsticas con drop statistics, puedes evitar que se
cree o se actualicen desde las opciones de configuracion de la base de


datos,
puedes create indices explicitos a la tabla temporal, puedes usar variables
tabla, etc.

Ahora si todo se hace mediante table scan (segun dejan mostrar la queries)
no entiendo el sentido tu duda de cambiar el plan.
Respuesta Responder a este mensaje
#3 Jose Mariano Alvarez
20/01/2006 - 15:43 | Informe spam
Puedes deshabilitar la creacion automatica de estadisticas y dejar habilitada
de de actualizacion.

Siempre hablando del 2000 puedes usar with recompile, una variable de tipo
tabla, forzar el plan o agregar indices a la tabla temporal.

Otra opcion es usar una tabla no temporal creada de antemano

En 2005 tienes alguna opcion mas como la selecion de los planes en cache.


Ing. Jose Mariano Alvarez

J0sé P-u-n-t-0 Marian0 P-u-n-t-0 Álvarez ** gma1l P-u-n-t-0 c0n <-- M
(Saca guiones, blancos, acentos, ceros por o)

http://www.sqlgurus.org


"Quique" wrote:


En vez de anidar una serie de sub-select, identificamos que era mucho mas
eficiente el crear una tabla temporal con los resultados de la sub-select
(sin borrarla despues, pues se podria reutilizar para otra secuencia).

De ahi, el primer CREATE y su posterior INSERT para rellenarla.

El SELECT cruza la tabla temporal con otro conjunto de tablas. La
estrategia es que haga un FULL a la tabla temporal y, para cada registro,
acceda a una de las tablas del conjunto por clave primaria (con NESTED
LOOP).

Si borro TODAS las estadisticas, estropeo todo. Necesitaria borrar solo
las estadisticas de la tabla temporal (la base de datos tiene
actualizacion automatica de las estadisticas y no querriamos cambiarlo).

?Se puede borrar las estadisticas de solo una tabla?

Gracias

Jose Mariano Alvarez wrote:

> Podrias aclarar mas cosas.
> No se entiende que quieres hacer.

> Puedes eliminar las estadirsticas con drop statistics, puedes evitar que se
> cree o se actualicen desde las opciones de configuracion de la base de
datos,
> puedes create indices explicitos a la tabla temporal, puedes usar variables
> tabla, etc.

> Ahora si todo se hace mediante table scan (segun dejan mostrar la queries)
> no entiendo el sentido tu duda de cambiar el plan.




Respuesta Responder a este mensaje
#4 Alejandro Mesa
20/01/2006 - 16:11 | Informe spam
Quique,

Es dificil dar una respuesta a esta pregunta, sin contar con la estructura
de las tablas que participan en el sp, incluyendo constraints e indices.

Para que quieres borrar las estadisticas, de todas maneras SQL Server
tratara de crearlas nuevamente (para las columnas que participen en en el
"join" o clausula "where" y no tengan indice asociado). Volver a crear las
estadisticas toma tiempo asi que no veo ganancia en la operacion como
conjunto. Como crees que SQL Server pueda decidir que plan de ejecucion tomar
si no tiene indices ni estadisticas?. Que tan bueno seria ese plan?

Una opcion seria la dada por Jose Mariano, crear indices en la tabla
temporal y otra, seria forzar a SQL Server a usar un determinado algoritmo de
ejecucion en la union (join_hint). Chequea la sentencia "select" en los BOL.

La otra opcion, tambien dada por Jose, de usar una variable tipo tabla,
puede que te sea util, pues SQL Server no crea estadisticas para ellas.


AMB


"Quique" wrote:


En vez de anidar una serie de sub-select, identificamos que era mucho mas
eficiente el crear una tabla temporal con los resultados de la sub-select
(sin borrarla despues, pues se podria reutilizar para otra secuencia).

De ahi, el primer CREATE y su posterior INSERT para rellenarla.

El SELECT cruza la tabla temporal con otro conjunto de tablas. La
estrategia es que haga un FULL a la tabla temporal y, para cada registro,
acceda a una de las tablas del conjunto por clave primaria (con NESTED
LOOP).

Si borro TODAS las estadisticas, estropeo todo. Necesitaria borrar solo
las estadisticas de la tabla temporal (la base de datos tiene
actualizacion automatica de las estadisticas y no querriamos cambiarlo).

?Se puede borrar las estadisticas de solo una tabla?

Gracias

Jose Mariano Alvarez wrote:

> Podrias aclarar mas cosas.
> No se entiende que quieres hacer.

> Puedes eliminar las estadirsticas con drop statistics, puedes evitar que se
> cree o se actualicen desde las opciones de configuracion de la base de
datos,
> puedes create indices explicitos a la tabla temporal, puedes usar variables
> tabla, etc.

> Ahora si todo se hace mediante table scan (segun dejan mostrar la queries)
> no entiendo el sentido tu duda de cambiar el plan.




Respuesta Responder a este mensaje
#5 e.lorenzo
23/01/2006 - 12:44 | Informe spam
Quizás me haya explicado mal o yo he llegado a una conclusión errónea.

La cuestión es que tengo tres sentencias (A, B y C). Si las lanzo
seguidas, el tiempo es óptimo. Si hago una pausa entre la B y la C, me
cambia el plan de ejecución de la C y tarda 10 veces más.

Pongo las consultas al final del Post. El problema es que es una
aplicación que hemos construido con un motor de SQL y tenemos ciertas
limitaciones para poner hints (aunque podéis ver al final que lo podemos
poner, pero en algunos informes nos penaliza). En cuanto al uso de tablas
temporales del sistema o las variables, también las usamos (mediante
parámetro, decidimos si usar tabla física, temporal, variable y física sin
borrado): en determinados informes nos da mejor rendimiento la última
opción y en el resto, pues unas veces unas y otras otra.

Gracias por vuestra paciencia.

Un saludo

SET NOCOUNT ON;

-A-
/* Creación de la tabla temporal */
CREATE TABLE dbo.TMPA17C22500300027000020275433 (ID_PLAN_CONTABLE varchar
(20) COLLATE Modern_Spanish_CI_AI NOT NULL, CONSTRAINT
PK_117C22500300027000020275433 PRIMARY KEY (ID_PLAN_CONTABLE)) ON
[PRIMARY];


-B-
/* Inserción en la tabla temporal */
INSERT INTO dbo.TMPA17C22500300027000020275433
SELECT DISTINCT D.ID_PLAN_CONTABLE FROM dbo.T_EBE_DGI_200412 D WHERE
D.FECHA_DATOS_INFORME_GENERADO = Convert(datetime,'31/12/2004',103)AND
D.SEC_INFORME_GENERADO = 2 AND D.ID_SUBINFORME = '00000100010'
AND D.ID_CASILLA IN
('0054900001','0056000001','0057000001','0058000001','0054900002','0054900003','0056000002','0056000003','0057000002','0057000003','0058000002','0058000003','0055000002','0055100002','0055200002','0055300002','0055400002','0055500002','0055800002','0055900002','0055000003','0055100003','0055200003','0055300003','0055400003','0055500003','0055800003','0055900003','0056100002','0056200002','0056300002','0056400002','0056500002','0056600002','0056900002','0056100003','0056200003','0056300003','0056400003','0056500003','0056600003','0056900003','0057100002','0057200002','0057300002','0057400002','0057500002','0057600002','0057900002','0057100003','0057200003','0057300003','0057400003','0057500003','0057600003','0057900003','0058100002','0059100002','0060100002','0058100003','0059100003','0060100003','0055600002','0055700002','0055600003','0055700003','0056700002','0056800002','0056700003','0056800003','0057700002','0057800002','0057700003','0057800003','0058200002','0058300002','0058400002','0058500002','0058600002','0058700002','0059000002','0058200003','0058300003','0058400003','0058500003','0058600003','0058700003','0059000003','0059200002','0059300002','0059400002','0059500002','0059600002','0059700002','0060000002','0059200003','0059300003','0059400003','0059500003','0059600003','0059700003','0060000003','0060200002','0060300002','0060400002','0060500002','0060600002','0060700002','0061000002','0060200003','0060300003','0060400003','0060500003','0060600003','0060700003','0061000003','0058800002','0058900002','0058800003','0058900003','0059800002','0059900002','0059800003','0059900003','0060800002','0060900002','0060800003','0060900003')AND
D.ID_PLAN_CONTABLE <>'-1';

SET NOCOUNT OFF;


-C-
/* Consulta */
SELECT DISTINCT '225003' ID_INFORME,Convert(datetime,'31/12/2004',103)
FECHA_DATOS_INFORME_GENERADO,1 SEC_INFORME_GENERADO,'22500300010'
ID_SUBINFORME,'-1' ID_VARIACION_1,'-1' ID_VARIACION_2,28 N_FILA_ABSOLUTO,3
C_COLUMNA_ABSOLUTO,A.ID_TIPO_REGISTRO ID_TIPO_REGISTRO,A.ID_TIPO_DATO
ID_TIPO_DATO,A.ID_APLICACION_ORIGEN
ID_APLICACION_ORIGEN,A.ID_PLAN_CONTABLE ID_PLAN_CONTABLE,A.ID_CONTRATO
ID_CONTRATO,'-1' ID_SUBINFORME_ORIGEN,'-1' ID_CASILLA_ORIGEN,-1
ORDEN_VARIACION_GLOBAL,-1 ORDEN_VARIACION_FILA,'-1' ID_VARIACION_FILA,'27'
ID_FILA,'0002700003' ID_CASILLA,'DATO'
ID_TIPO_CASILLA,A.ID_ENTIDAD_CONTABLE
ID_ENTIDAD_CONTABLE,A.ID_CENTRO_CONTABLE
ID_CENTRO_CONTABLE,A.ID_DIVISA_CONTABLE ID_DIVISA_CONTABLE,null
COMENTARIO_CASILLA_DETAL_INFOR,'0527' CODIGO_CASILLA,A.TIPO_IMPORTE
TIPO_IMPORTE,A.ID_PRODUCTO ID_PRODUCTO, (A.IMPORTE_EUROS ) VALOR,
(A.IMPORTE_DIVISA_CONTRATO ) VALOR_DIVISA_ORIGINAL,'MILES'
FORMATO,Convert(datetime,'17/01/2006',103) FECHA_ALTA_DETALLE_INFORME,null
FECHA_BAJA_DETALLE_INFORME,Convert(datetime,'17/01/2006',103)
FECHA_MODIF,'' DESC_VARIACION_1,'' DESC_VARIACION_2,''
DESC_VARIACION_FILA,'-1' ID_VARIACION_1_ORIGEN,'-1'
ID_VARIACION_2_ORIGEN,'-1'
ID_VARIACION_FILA_ORIGEN,Convert(datetime,'01/01/1900',103)
FECHA_DATOS_INFORME_ORIGEN,-1 SEC_INFORME_GENERADO_ORIGEN,''
DESC_VARIACION_1_ORIGEN,'' DESC_VARIACION_2_ORIGEN,''
DESC_VARIACION_FILA_ORIGEN,TIPO_CARTERA TIPO_CARTERA,CAMP001
CAMP001,CAMP002 CAMP002,CAMP003 CAMP003,CAMP004 CAMP004,CAMP005
CAMP005,CAMP006 CAMP006,CAMP007 CAMP007,CAMP008 CAMP008,CAMP009
CAMP009,CAMP010 CAMP010 ,A.ID_PAIS_CENTRO_CONTABLE
ID_PAIS_CENTRO_CONTABLE,A.ID_PROVINCIA_CENTRO_CONTABLE
ID_PROVINCIA_CENTRO_CONTABLE,A.ID_SECTOR_ENTIDAD_CONTABLE
ID_SECTOR_ENTIDAD_CONTABLE,0 N_AJUSTE,null USUARIO_AJUSTE
FROM
TMPA17C22500300027000020275433 E,
T_EBE_DMB_200412 A,
T_EBE_CC_200412 B,
T_EBE_DC_200412 C ,
T_EBE_ELEMENTOS z0 ,
T_EBE_RELACIONES_TABLAS r0,
T_EBE_ELEMENTOS z2 ,
T_EBE_RELACIONES_TABLAS r2
WHERE
(A.ID_CONTRATO=B.ID_CONTRATO AND A.ID_MES=B.ID_MES)
AND (B.ID_CONTRATO=C.ID_CONTRATO AND B.ID_MES=C.ID_MES)
AND A.ID_PLAN_CONTABLE=E.ID_PLAN_CONTABLE
AND r0.ID_TABLA_1='8080'
AND r0.FECHA_ALTA_RELACION<=CONVERT(DATETIME,'31/12/2004',103)
AND
ISNULL(r0.FECHA_BAJA_RELACION,CONVERT(DATETIME,'31/12/2999',103))>=CONVERT(DATETIME,'31/12/2004',103)
AND r0.ID_ELEMENTO_2=A.ID_ENTIDAD_CONTABLE AND r0.ID_TABLA_2='2080' AND
z0.ID_TABLA='2080'
AND z0.ID_ELEMENTO=r0.ID_ELEMENTO_2 AND
z0.FECHA_ALTA_ELEMENTO<=Convert(datetime,'31/12/2004',103)
AND
isnull(z0.FECHA_BAJA_ELEMENTO,Convert(datetime,'31/12/2999',103))>=Convert(datetime,'31/12/2004',103)

AND r2.ID_TABLA_1='6230' AND
r2.FECHA_ALTA_RELACION<=CONVERT(DATETIME,'31/12/2004',103)
AND
ISNULL(r2.FECHA_BAJA_RELACION,CONVERT(DATETIME,'31/12/2999',103))>=CONVERT(DATETIME,'31/12/2004',103)
AND r2.ID_ELEMENTO_2=B.DISC023 AND r2.ID_TABLA_2='0230'
AND z2.ID_TABLA='0230'
AND z2.ID_ELEMENTO=r2.ID_ELEMENTO_2 AND
z2.FECHA_ALTA_ELEMENTO<=Convert(datetime,'31/12/2004',103)
AND
isnull(z2.FECHA_BAJA_ELEMENTO,Convert(datetime,'31/12/2999',103))>=Convert(datetime,'31/12/2004',103)

AND (((A.ID_TIPO_DATO in ('01')))
AND (( r0.ID_ELEMENTO_1 in ('01')))
AND ((A.ID_PAIS_CENTRO_CONTABLE in ('0724')))

AND (( (B.DISC020 NOT IN
(
SELECT r100.ID_ELEMENTO_2
FROM T_EBE_ELEMENTOS z100 ,T_EBE_RELACIONES_TABLAS r100
WHERE 1=1 AND r100.ID_TABLA_1='6200' AND r100.ID_ELEMENTO_1
IN('BE.UEM1.008')
AND r100.FECHA_ALTA_RELACION<=CONVERT(DATETIME,'31/12/2004',103) AND
ISNULL(r100.FECHA_BAJA_RELACION,CONVERT(DATETIME,'31/12/2999',103))>=CONVERT(DATETIME,'31/12/2004',103)
AND r100.ID_TABLA_2='0200' AND z100.ID_TABLA='0200' AND
z100.ID_ELEMENTO=r100.ID_ELEMENTO_2
AND z100.FECHA_ALTA_ELEMENTO<=Convert(datetime,'31/12/2004',103)
AND
isnull(z100.FECHA_BAJA_ELEMENTO,Convert(datetime,'31/12/2999',103))>=Convert(datetime,'31/12/2004',103)
)
OR B.DISC020 IS NULL
)
))

AND (( r2.ID_ELEMENTO_1 in ('BE.UEM1.001')))

AND (( (B.DISC033 NOT IN (
SELECT r102.ID_ELEMENTO_2 FROM T_EBE_ELEMENTOS z102
,T_EBE_RELACIONES_TABLAS r102
WHERE 1=1 AND r102.ID_TABLA_1='6330' AND r102.ID_ELEMENTO_1
IN('BE.UEM1.001', 'BE.UEM1.002')
AND r102.FECHA_ALTA_RELACION<=CONVERT(DATETIME,'31/12/2004',103)
AND
ISNULL(r102.FECHA_BAJA_RELACION,CONVERT(DATETIME,'31/12/2999',103))>=CONVERT(DATETIME,'31/12/2004',103)
AND r102.ID_TABLA_2='0330' AND z102.ID_TABLA='0330' AND
z102.ID_ELEMENTO=r102.ID_ELEMENTO_2
AND z102.FECHA_ALTA_ELEMENTO<=Convert(datetime,'31/12/2004',103)
AND
isnull(z102.FECHA_BAJA_ELEMENTO,Convert(datetime,'31/12/2999',103))>=Convert(datetime,'31/12/2004',103)
)
OR B.DISC033 IS NULL
)
))

AND (( (A.ID_DIVISA_CONTABLE NOT IN ('0978') OR A.ID_DIVISA_CONTABLE IS
NULL ))) )
AND A.ID_MES=Convert(datetime,'31/12/2004',103)
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida