Tengo una mesa ItemValue completa de los datos en un servidor SQL 2005 se ejecuta en modo de compatibilidad de 2000, que se ve algo como (Es una tabla los valores definidos por el usuario):Optimización de SQL: cambios en el plan de ejecución en función del valor de restricción. ¿Por qué?
ID ItemCode FieldID Value
-- ---------- ------- ------
1 abc123 1 D
2 abc123 2 287.23
4 xyz789 1 A
5 xyz789 2 3782.23
6 xyz789 3 23
7 mno456 1 W
9 mno456 3 45
... and so on.
fieldID proviene de la Itemfield tabla:
ID FieldNumber DataFormatID Description ...
-- ----------- ------------ -----------
1 1 1 Weight class
2 2 4 Cost
3 3 3 Another made up description
. . x xxx
. . x xxx
. . x xxx
x 91 (we have 91 user-defined fields)
Porque puedo no pivota en el modo 2000, estamos atrapados construir una consulta fea utilizando casos y GROUP BY para obtener los datos que debe buscar la forma en que deberían para s ome aplicaciones de legado, que es:
ItemNumber Field1 Field2 Field3 .... Field51
---------- ------ ------- ------
abc123 D 287.23 NULL
xyz789 A 3782.23 23
mno456 W NULL 45
Usted puede ver sólo tenemos esta tabla para mostrar valores de hasta el 51 UDF. Aquí está la consulta:
SELECT
iv.ItemNumber,
,MAX(CASE WHEN f.FieldNumber = 1 THEN iv.[Value] ELSE NULL END) [Field1]
,MAX(CASE WHEN f.FieldNumber = 2 THEN iv.[Value] ELSE NULL END) [Field2]
,MAX(CASE WHEN f.FieldNumber = 3 THEN iv.[Value] ELSE NULL END) [Field3]
...
,MAX(CASE WHEN f.FieldNumber = 51 THEN iv.[Value] ELSE NULL END) [Field51]
FROM ItemField f
LEFT JOIN ItemValue iv ON f.ID = iv.FieldID
WHERE f.FieldNumber <= 51
GROUP BY iv.ItemNumber
Cuando el FieldNumber restricción es < = 51, el plan de ejecución es algo como:
SELECT <== Computer Scalar <== Stream Aggregate <== Sort (Cost: 70%) <== Hash Match <== (Clustered Index Seek && Table Scan)
y es rápido! Puedo retirar más de 100.000 registros en aproximadamente un segundo, lo que se adapta a nuestras necesidades.
Sin embargo, si tuviéramos más UDF y yo cambiamos la restricción a cualquier cosa por encima (sí, yo los probé uno a uno) o si elimino por completo, pierdo el tipo en el plan de ejecución, y se reemplaza con un montón de bloques de Paralelismo que reúnen, reparten y distribuyen transmisiones, y todo es lento (30 segundos incluso por solo 1 registro).
FieldNumber tiene una, índice único agrupado, y es parte de la clave primaria de material compuesto con el columna ID (índice no agrupado) en el tabla Itemfield. ID y ItemNumber columnas del ItemValue de mesa hacen una PK, y hay un índice no agrupado adicional en la columna de la ItemNumber.
¿Cuál es el razonamiento detrás de esto? ¿Por qué el cambio de mi restricción de entero simple cambia todo el plan de ejecución?
Y si está a la altura ... ¿qué harías de manera diferente? Hay una actualización SQL planificada para un par de meses a partir de ahora, pero necesito solucionar este problema antes de eso.
Lo que haría de manera diferente no es usar esa estructura de tabla. Es mucho mejor usar una estructura con campos definidos para el 99% de las necesidades de datos que se pueden descifrar de antemano que para usar una tabla EAV. Dicho sea de paso, el modo de compatilidad no impide el uso de nuevas funciones, sino que permite el uso de funciones que ya no están permitidas. Sin embargo, si está desarrollando una base de datos de 2005 con una base de datos de producción 2000, es mejor evitar las nuevas características. – HLGEM