D R . M I G U E L Á N G E L O R O S H E R N Á N D E Z
Database tunning
Optimización de consultas
Volver más eficiente la estrategia de procesamiento de las consultas
Necesidad de optimizarSELECT C.name, C.address
FROM customer C, account A
WHERE c.customer_name = A.customer_name
AND A.balance > 2000
Formas de ejecución𝜋𝐶.𝑐𝑢𝑠𝑡𝑜𝑚𝑒𝑟_𝑛𝑎𝑚𝑒,𝐶.𝑎𝑑𝑑𝑟𝑒𝑠𝑠 ቀ
ቁ
𝜎𝐶.𝑐𝑢𝑠𝑡𝑜𝑚𝑒𝑟𝑛𝑎𝑚𝑒=𝐴.𝑐𝑢𝑠𝑡𝑜𝑚𝑒𝑟𝑛𝑎𝑚𝑒∧𝐴.𝑏𝑎𝑙𝑎𝑛𝑐𝑒>2000ሺ
ሻ
𝐶
× 𝐴
𝜋𝐶.𝑐𝑢𝑠𝑡𝑜𝑚𝑒𝑟_𝑛𝑎𝑚𝑒,𝐶.𝑎𝑑𝑑𝑟𝑒𝑠𝑠 ቀ
ቁ
𝜎𝐶.𝑐𝑢𝑠𝑡𝑜𝑚𝑒𝑟_𝑛𝑎𝑚𝑒=𝐴.𝑐𝑢𝑠𝑡𝑜𝑚𝑒𝑟_𝑛𝑎𝑚𝑒൫
൯
𝐶
× 𝜎𝐴.𝑏𝑎𝑙𝑎𝑛𝑐𝑒>2000 𝐴
Optimización global de queriesbasic distributed query processing strategies - example
𝑅 ⋈ 𝑆R A B
3 7
1 1
4 6
7 7
4 5
6 2
5 7
S B C D
9 8 8
1 5 1
9 4 2
4 3 3
4 2 6
5 7 8
A B C D
1 1 5 1
4 5 7 8
Optimización global de queriesbasic distributed query processing strategies – ship whole
𝑅 ⋈ 𝑆R A B
3 7
1 1
4 6
7 7
4 5
6 2
5 7
S B C D
9 8 8
1 5 1
9 4 2
4 3 3
4 2 6
5 7 8
A B C D
1 1 5 1
4 5 7 8
Optimización global de queriesbasic distributed query processing strategies – ship whole
𝑅 ⋈ 𝑆R A B
3 7
1 1
4 6
7 7
4 5
6 2
5 7
S B C D
9 8 8
1 5 1
9 4 2
4 3 3
4 2 6
5 7 8
A B C D
1 1 5 1
4 5 7 8
Optimización global de queriesbasic distributed query processing strategies – ship whole
𝑅 ⋈ 𝑆R A B
3 7
1 1
4 6
7 7
4 5
6 2
5 7
S B C D
9 8 8
1 5 1
9 4 2
4 3 3
4 2 6
5 7 8
A B C D
1 1 5 1
4 5 7 8
Optimización global de queriesbasic distributed query processing strategies – Fetch as needed
𝑅 ⋈ 𝑆R A B
3 7
1 1
4 6
7 7
4 5
6 2
5 7
S B C D
9 8 8
1 5 1
9 4 2
4 3 3
4 2 6
5 7 8
A B C D
1 1 5 1
4 5 7 8
Optimización global de queriesbasic distributed query processing strategies – Fetch as needed
𝑅 ⋈ 𝑆R A B
3 7
1 1
4 6
7 7
4 5
6 2
5 7
S B C D
9 8 8
1 5 1
9 4 2
4 3 3
4 2 6
5 7 8
A B C D
1 1 5 1
4 5 7 8
Optimización global de queriesbasic distributed query processing strategies – Ship whole vs. Fetch as needed
Conclusion
Fetch as need results in a high number of messages
Ship whole results in high amounts of transfered data
More advanced strategies based on these two basic strategies
Semijoin
Bitvector-join
Optimización global de queriesbasic distributed query processing strategies – semijoin
Op
tim
iza
ció
n g
lob
al
de
qu
erie
sb
asi
cd
istr
ibu
ted
qu
ery
pro
cess
ing
stra
teg
ies–
sem
ijo
in
Optimización global de queriesbasic distributed query processing strategies – Bitvector join
Optimización global de queriesbasic distributed query processing strategies – Bitvector join
Op
tim
iza
ció
n g
lob
al
de
qu
erie
sb
asi
cd
istr
ibu
ted
qu
ery
pro
cess
ing
stra
teg
ies–
Bit
vec
tor
join
[ 0 1 1 0 1 1 0]
[ 0 1 1 0 11 0]
Optimización global de queriesbasic distributed query processing strategies – Bitvector join
Optimización de consultasGuías generales
Ejecutar las selecciones y las proyecciones lo más pronto posible
Dividir la expresión si es necesario
Agregar proyecciones para eliminar las columnas no utilizadas
Eliminar o reducir los cálculos repetidos
Combinar las operadores unarios con los operadores binarios
Optimización de consultasestrategias de optimización
Optimización basada en heurísticas
Realizar las selecciones y las proyecciones lo más pronto posible
Eliminar los cálculos duplicados
Optimización basada en costos
Estimar el costo de las diferentes expresiones equivalentes del query
Seleccionar el plan de ejecución con menor costo
Optimización de consultastransformaciones heurísticas: transformaciones basadas en las selecciones y proyecciones
Selección en cascada𝜎𝑐𝑜𝑛𝑑1∧𝑐𝑜𝑛𝑑2 𝑅 ≡ 𝜎𝑐𝑜𝑛𝑑1 𝜎𝑐𝑜𝑛𝑑2 𝑅
Conmutatividad de la selección𝜎𝑐𝑜𝑛𝑑1 𝜎𝑐𝑜𝑛𝑑2 𝑅 ≡ 𝜎𝑐𝑜𝑛𝑑2 𝜎𝑐𝑜𝑛𝑑1 𝑅
Proyección en cascada
𝜋𝑎𝑡𝑡𝑟𝑖𝑏1 𝜋𝑎𝑡𝑡𝑟𝑖𝑏2 … 𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑛 𝑅 ≡ 𝜋𝑎𝑡𝑡𝑟𝑖𝑏1 𝑅
Conmutatividad de la selección y la proyección𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠 𝜎𝑐𝑜𝑛𝑑 𝑅 ≡ 𝜎𝑐𝑜𝑛𝑑 𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠 𝑅
Optimización de consultastransformaciones heurísticas
Transladar las selecciones y las proyecciones hacia los joins
𝜎𝑐𝑜𝑛𝑑 𝑅 × 𝑆 ≡ 𝑅 ⋈𝑐𝑜𝑛𝑑 𝑆
Si las condiciones cond se relaciona con los atributos de R y S𝜎𝑐𝑜𝑛𝑑 𝑅 × 𝑆 ≡ 𝜎𝑐𝑜𝑛𝑑 𝑅 × 𝑆
Si los todos atributos en cond pertenecen a R (ídem con los joins)
𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠1 𝑅 × 𝑆 ≡ 𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠1 𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠2 𝑅 × 𝑆
Donde 𝑎𝑡𝑡𝑟𝑖𝑏𝑠1 ⊆ 𝑎𝑡𝑡𝑟𝑖𝑏𝑠2 ⊆ 𝑎𝑡𝑟𝑖𝑏𝑢𝑡𝑜𝑠 𝑑𝑒 𝑅
𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠1 𝑅 ⋈𝑐𝑜𝑛𝑑 𝑆 ≡ 𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠1 𝜋𝑎𝑡𝑡𝑟𝑖𝑏𝑠2 𝑅 ⋈𝑐𝑜𝑛𝑑 𝑆
Todos los atributs que figuran en 𝑎𝑡𝑡𝑟𝑖𝑏𝑠2 están cond
Optimización de consultasárboles de consultas (query trees): definición
Es una estructura arbórea que corresponde a la expresión en álgebra relacional tal que
Cada nodo hoja representa una relación de entrada
Cada nodo interno representa una relación obtenida por la aplicación de un operador relacional a sus hijos
La relación raíz representa la respuesta a la consulta (query)
Optimización de consultasárboles de consultas (query trees)
Dos árboles de consulta son equivalentes si las relaciones raíz son iguales
Un árbol de consulta puede tener diferentes planes de ejecución
Algunos árboles de consulta y planes de ejecución son más eficientes que otros en la ejecución
Optimización de consultasejemplo de árbol de consulta
𝜋𝑠𝑛𝑎𝑚𝑒
𝜎𝑏𝑖𝑑=100∧𝑟𝑎𝑡𝑖𝑛𝑔>5
⋈𝑠𝑖𝑑=𝑠𝑖𝑑
𝑅𝑒𝑠𝑒𝑟𝑣𝑒𝑠 𝑆𝑎𝑖𝑙𝑜𝑟𝑠
Optimización de consultasplanes de ejecución
Árbol de operadores de álgebra relacional
Idealmente: hallar el mejor plan
En la práctica: ¡evitar los peores planes!
Optimización de consultasinformación almacenada en el system catalog
Por cada relación Nombre de la relación, estructura, nombre del archivo
Nombre y tipos de todos los atributos
Nombres de todos los índices de la relación
Restricciones de integridad asociadas a la relación
Por cada índice nombre y estructura del índice
Atributos llave utilizados en las búsquedas
Por cada vista Nombre y definición de la vista
Optimización de consultasestadísticas almacenadas
Cardinalidad: número de registros en la cada relación
Tamaño: número de páginas por cada relación
Cardinalidad del índice: número de valores distintos en las llaves
Tamaño del índice: número de páginas por cada índice
Altura del índice: número de niveles no hoja para cada árbol índice
…
Optimización de consultasevaluación de los joins
𝑅 ⋈ 𝑆 es muy común; por lo tanto, debe ser optimizada cuidadosamente
Si 𝑅 × 𝑆 es muy grande, entonces 𝑅 × 𝑆 seguida de una selección es muy ineficiente
Evaluaciones de joins
Simple nested loop join
Block nested loop join
Index nested loop join
Sort-merge join
Hash join
Optimización de consultasalgunas técnicas
Evitar el uso de * en las sentencias SELECT
EjemploSELECT * FROM student_details
Remplazar por
SELECT id, first_name, last_name,
age, subject
FROM student_details
Optimización de consultasalgunas técnicas
Utilizar la cláusula SELECT sólo para filtrar los grupos
EjemploSELECT subject, COUNT(subject)
FROM student_details
WHERE subject != ‘Science’ AND subject != ‘Maths’
GROUP BY subject
HAVING subject != ‘Vancouver’ AND subject !=
‘Toronto’
Remplazar por
SELECT subject, COUNT(subject)
FROM student_details
WHERE subject != ‘Science’ AND subject != ‘Maths’
GROUP BY subject
Optimización de consultasalgunas técnicas
Tratar de minimizar el número de subqueries
EjemploSELECT name
FROM employee
WHERE salary = (SELECT MAX(salary) FROM employee_details)
AND age = (SELECT MAX(age) FROM employee_details)
AND emp_dept = 'Electronics'
Remplazar por
SELECT name
FROM employee
WHERE (salary, age) = (SELECT MAX(salary), MAX (age)
FROM employee_details)
AND dept = 'Electronics'
Optimización de consultasalgunas técnicas
Usar los operadores EXISTS e IN así como los
joins correctamente
Generalmente, el operador IN no tiene un buen
desempeño
El operador IN es eficiente cuando se utiliza en
subqueries
El operador EXISTS es eficiente cuando se utiliza en la
consulta principal
Optimización de consultasalgunas técnicas
EjemploSELECT * FROM product
WHERE product_id IN
(SELECT product_id FROM order_items)
Remplazar por
SELECT * FROM product p
WHERE EXISTS(SELECT 1 FROM order_items o
WHERE o.product_id = p.product_id)
Optimización de consultasalgunas técnicas
Usar EXISTS en lugar de DISTINCT cuando los
joins involucran tablas con relaciones uno a muchos
EjemploSELECT DISTINCT d.dept_id, d.dept
FROM dept d,employee e
WHERE e.dept = e.dept
Remplazar por
SELECT d.dept_id, d.dept
FROM dept d
WHERE EXISTS(SELECT 1 FROM employee e
WHERE e.dept = d.dept)
Optimización de consultasalgunas técnicas
Tratar de usar UNION ALL en lugar de UNION
EjemploSELECT id, first_name, subject
FROM student_details_class10
UNION
SELECT id, first_name
FROM sports_team
Remplazar por
SELECT id, first_name, subject
FROM student_details_class10
UNION ALL
SELECT id, first_name
FROM sports_team
Optimización de consultasalgunas técnicas
Ser cuidadoso con las condiciones colocadas en la cláusula WHERE
Ejemplo 1SELECT id, first_name, age FROM student_details
WHERE age != 10
Remplazar por
SELECT id, first_name, age FROM student_details
WHERE age > 10
Optimización de consultasalgunas técnicas
Ejemplo 2SELECT id, first_name, age
FROM student_details
WHERE SUBSTR(first_name,1,3) = 'Cha'
Remplazar por
SELECT id, first_name, age
FROM student_details
WHERE first_name LIKE 'Cha%'
Optimización de consultasalgunas técnicas
Ejemplo 3SELECT id, first_name, age
FROM student_details
WHERE first_name = NVL(:name, first_name)
Remplazar por
SELECT id, first_name, age
FROM student_details
WHERE first_name LIKE NVL(:name, '%')
Optimización de consultasalgunas técnicas
Ejemplo 4SELECT product_id, product_name
FROM product
WHERE unit_price >= MAX(unit_price)
AND unit_price <= MIN(unit_price)
Remplazar por
SELECT product_id, product_name
FROM product
WHERE unit_price BETWEEN MAX(unit_price) AND
MIN(unit_price)
Optimización de consultasalgunas técnicas
Ejemplo 5SELECT id, name, salary
FROM employee
WHERE dept || location= 'ElectronicsBangalore'
Remplazar por
SELECT id, name, salary
FROM employee
WHERE dept = 'Electronics'
AND location = 'Bangalore'
Optimización de consultasalgunas técnicas
Usar expresiones, que no involucren campos o columnas, en uno solo lado porque se procesan mejor
Ejemplo 1SELECT id, name, salary
FROM employee
WHERE salary + 10000 < 35000
Remplazar por
SELECT id, name, salary
FROM employee
WHERE salary < 25000
Optimización de consultasalgunas técnicas
Ejemplo 2SELECT id, first_name, age
FROM student_details
WHERE age NOT = 10
Remplazar por
SELECT id, first_name, age
FROM student_details
WHERE age > 10
Optimización de consultasalgunas técnicas
Usar DECODE para evitar el barrido de los mismos
registros o el join con la misma tabla de manera repetida
EjemploSELECT id FROM employee
WHERE name LIKE 'Ramesh%'
and location = 'Bangalore‘
Remplazar por
SELECT DECODE(location,'Bangalore',id,NULL) id
FROM employee
WHERE name LIKE 'Ramesh%'
Optimización de consultasalgunas técnicas
Para almacenar large binary objects, primero debe colocarlos en el sistema de archivos y después agregar la ruta del archivo en la base de datos
Consejos para el diseño de bases de datos
1. Planear primero antes de implementar
2. Utilizar el modelo entidad relación
3. Seleccionar cuidadosamente las llaves primarias
4. Seleccionar los tipos de datos teniendo en mente optimizar el espacio
5. Asegurarse que los atributos esté definidos para un solo propósito
6. Recordar el significado de NULL
7. Normalizar siempre que sea posible
8. Administrar las relaciones
9. Usar nombres descriptivos
10. Documentar el diseño
Factores
1. Diseño de la base de datos
2. Indexación apropiada
3. Configuraciones (base de datos, instancia de SQL, sistema operativo)
4. Estadísticas actualizadas
5. Hardware
6. Desempeño de la red
Mejores prácticas en la formulación de consultas
No usar DISTINCT o UNION en lugar de UNION ALL si los
registros únicos no son necesarios
Tener cuidado con probar sin datos
Utilizar los cursores como última opción. Si se usan, asegurarse de colocar CLOSE y DEALLOCATE
Evitar hacer uso de los query hints
Evitar anidar vistas
Utilizar procedimientos almacenados
Mejores prácticas en la formulación de consultas
Especificar las columnas que se necesitan en el SELECT
Reducir el número de registros que regresa una consulta, hacer uso del WHERE
Mantener bajo control la cláusula FROM
Dividir un query complejo consumidor de tiempo en pequeños queries
Usar ORDER BY solamente si es necesario presentar
ordenados los resultados
Evitar conversiones de datos implícitas en las cláusulas FROM, WHERE y HAVING
Captura y evaluación de desempeño de consultasconsultas en ejecución
SELECT r.session_id, r.status, r.start_time,
r.command, s.text
FROM sys.dm_exec_requests r
CROSS APPLY sys.dm_exec_sql_text(r.sql_handle) s
WHERE r.status = 'running'
Captura y evaluación de desempeño de consultasplan de ejecución
Costo
Index scan vs Table scan
Estadísticas faltantes
Costo del sort o de otras actividades
Discrepancias entre los registros estimados y los actuales
Clustered index vs Nonclustered index
Conversiones implícitas de tipos de datos
Captura y evaluación de desempeño de consultasClustered index vs Nonclustered index
Clustered index Nonclustered index
Guía sobre el uso de índices
Tipo: clustered index
Campos incrementales (identity, newsequentialid, …)
Conveniente para seleccionar rangos de valores, ordenar o agrupar
Llave primaria clustered index
Tipo: nonclusteredindex
Búsquedas por valores específicos
Índices compuestos conveniente utilizar Nonclustered index
Captura y evaluación de desempeño de consultasplan de ejecución: comandos
SET SHOWPLAN_ALL {ON | OFF}
Plan de ejecución en formato tabular, múltiples columnas y renglones
Inclusión de I/O y CPU para cada operación, registros estimados involucrados en la operación, costo de la operación, y los operadores lógicos y físicos utilizados
SET SHOWPLAN_TEXT {ON | OFF}
Regresa los datos en una columna con múltiples registros para cada operación
SET SHOWPLAN_XML {ON | OFF}
Regresa los datos en una columna con múltiples registros para cada operación en formato XML
Captura y evaluación de desempeño de consultasdesplegado de información en tiempo de ejecución
STATISTICS
Regresa información sobre las consultas que están ejecutándose en SQL Server
SET STATISTICS IO {ON | OFF}
Regresa las estadísticas de la actividad de disco (I/O) generada por la consulta
SET STATISTICS TIME {ON | OFF}
Regresa el número de milisegundos utilizados para revisar sintaxis, compilar y ejecutar cada sentencia
SET STATISTICS PROFILE {ON | OFF}
Equivalente a SET SHOWPLAN_ALL
SET STATISTICS XML {ON | OFF}
Equivalente a SET SHOWPLAN_XML
Captura y evaluación de desempeño de consultasidentificación del “cuello de botella”
¡SQL Server está lento!
¿razones?
Problema de desempeño
Problema atribuible a un cambio o evento aleatorio
Pero no hay evidencia de lo que sucede
sys.dm_os_wait_stats
Reinicio de SQL Server: borrado de las estadísticas
Técnica explicada en http://technet.microsoft.com/en-us/sqlserver/bb331794.aspx
Captura y evaluación del desempeño de consultasI/O contention
SELECT DB_NAME(database_id) DatabaseNM,
file_id FileID,
io_stall IOStallsMs,
size_on_disk_bytes FileBytes,
num_of_bytes_written BytesWritten,
num_of_bytes_read BytesRead
FROM sys.dm_io_virtual_file_stats(NULL, NULL)
ORDER BY io_stall DESC
I/O statistics, ordenados por I/O stallsI/O Stall: medido en milisegundos y representa el tipo total que los usuarios tienen que esperar para realizar operaciones de lectura o escritura
Afinación de índices
Identificar fragmentación reconstrucción o reorganización
Desplegar uso de índices
Afinación de índicesmejores prácticas sobre los índices
Agregar índices basados en la alta prioridad de las consultas
No agregar demasiados índices al mismo tiempo
Agregar siempre un clustered index a cada tabla
Monitorear el desempeño de las consultas
Mantener al mínimo la fragmentación de los índices por medio de la reconstrucción y/o reorganización
Seleccionar llaves para los clustered indexes que rara vez sean modificados, sean únicos y su tipo de dato no sea muy grande
Afinación de índicesmejores prácticas sobre los índices
Evitar índices con llaves grandes
Probar siempre los índices que consideran llaves compuestas
Tratar de anticipar cuales índices serán necesarios
Afinación de índicesindex fragmentation
sys.dm_db_index_physical_stats regresa el
nivel de fragmentación
sys.dm_db_index_physical_stats (
{ database_id | NULL }
, { object_id | NULL }
, { index_id | NULL | 0 }
, { partition_number | NULL }
, { mode | NULL | DEFAULT }
)
Afinación de índicesindex fragmentation
SELECT OBJECT_NAME(object_id) ObjectName,
index_id, index_type_desc,
avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats
(DB_ID('bancaria'),NULL, NULL, NULL, 'LIMITED')
WHERE avg_fragmentation_in_percent > 30
ORDER BY OBJECT_NAME(object_id)
Afinación de índicesindex fragmentation
SELECT OBJECT_NAME(f.object_id) ObjectName,
i.name IndexName, f.index_type_desc,
f.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats
(DB_ID('bancaria'),
OBJECT_ID(‘branch'),
OBJECT_ID(‘IX_branch’),
NULL, 'LIMITED') f
INNER JOIN sys.indexes i ON
i.object_id = f.object_id AND
i.index_id = f.index_id
Afinación de índicesuso de índices
Los índices pueden alentar las modificaciones a los datos mientras que aceleran las consultas con SELECT
Propuesta: balancear actividad de lectura vs actividad de modificación
Identificar los índices no utilizados: sys.dm_db_index_usage_stats
Afinación de consultasuso de índices
SELECT i.name IndexName, user_seeks,
user_scans, last_user_seek,
last_user_scan
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON
s.object_id = i.object_id AND
s.index_id = i.index_id
WHERE database_id = DB_ID('bancaria') AND
s.object_id = OBJECT_ID('branch')
Estadísticas
críticas para el procesamiento y desempeño de consultas
utilizadas por SQL Server para la generación de planes de ejecución
generadas manual o automáticamente opción AUTO_CREATE_STATISTICS
permite la actualización automática de estadísticas sobre tablas o índices
utilizar sp_updatestats después de un carga masiva
Estadísticasgeneración manual
CREATE STATISTICS statistics_name
ON { table | view } ( column [ ,...n ] )
[ WITH
[ [ FULLSCAN
| SAMPLE number { PERCENT | ROWS }
| STATS_STREAM = stats_stream ] [ , ] ]
[ NORECOMPUTE ]
]
Estadísticasgeneración manual: ejemplo
CREATE STATISTICS
Stats_Branch_BranchName
ON branch(branch_name)
WITH FULLSCAN
Estadísticasgeneración manual con un subconjunto de registros
CREATE STATISTICS
Stats_Branch_AssetsFiltrado
ON branch(assets)
WHERE assets >= 1700000
AND assets <= 9000000
WITH FULLSCAN
Estadísticasactualización manual
UPDATE STATISTICS table | view
[
{
{ index | statistics_name }
| ( { index |statistics_name } [ ,...n ] )
}
]
[ WITH
[
[ FULLSCAN ]
| SAMPLE number { PERCENT | ROWS }
| RESAMPLE
]
[ , ] [ ALL | COLUMNS | INDEX ]
[ [ , ] NORECOMPUTE ]
]
Estadísticasactualización manual: ejemplo
UPDATE STATISTICS deposit
WITH FULLSCAN
Estadísticasgeneración y actualización de estadísticas para todas las tablas
sp_createstats [ [ @indexonly = ] 'indexonly' ]
[ , [ @fullscan = ] 'fullscan' ]
[ , [ @norecompute = ] 'norecompute' ]
Ejemplos de invocaciónEXEC sp_createstats
EXEC sp_updatestats
Técnicas varias
Usar sp_executesql como alternativa a los
queries dinámicos y los procedimientos almacenados
Forzar al uso de un plan de ejecución en particular
Aplicar query hints
Técnicas variassp_executesql
EXEC (‘SELECT branch_name FROM branch’)
Riesgos:
1. SQL injection
2. Performance
Sintaxissp_executesql [ @stmt = ] stmt
[
{, [@params=] N'@parameter_name data_type [ OUT |
OUTPUT ][,...n]' }
{, [ @param1 = ] 'value1' [ ,...n ] }
]
Fin