BuenasPracticas Estandares SQL-Server
BuenasPracticas Estandares SQL-Server
BuenasPracticas Estandares SQL-Server
pe
Buenas Prcticas Base de Datos SQL Server
Estndares Transact-SQL
Buenas Prcticas de
Programacin
Pgina 1 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
Pgina 2 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
GEN.Employee
Pgina 3 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
Incorrecto:
DB_Ventas
Correcto:
Ventas
FechaRegistro
Responsable
Maquina
IP
4. Evite crear campos que acepten NULLs, solo aplquelo para los
campos que realmente lo requiera.
Pgina 4 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
Al ejecutar sentencias tipo DML en un procedimiento almacenado,
el servidor SQL regresa un mensaje indicando el nmero de filas
afectadas por el proceso. Aunque esta informacin puede ser til
para depurar el cdigo, resulta obsoleta si no se est depurando. Al
establecer el uso de SET NOCOUNT ON, se desactiva la funcin
de retorno de esta informacin adicional. En procedimientos
almacenados formados por varias instrucciones o declaraciones de
sentencias DML, habilitar SET NOCOUNT ON puede ayudarnos a
conseguir un aumento de rendimiento considerable, adems, si
tomamos en cuenta una base de datos que contenga decenas de
Procedimientos Almacenados para uso en una aplicacin orientada
a mltiples clientes al mismo tiempo, un detalle tan sencillo como
este puede aportar una diferencia notable. Se podra usar a modo
de ejemplo el siguiente esqueleto:
CREATE PROC dbo.StoreProcedureExample
(
@variable_1 INT,
@variable_2 VARCHAR(10),
@variable_n BIT
)
AS
BEGIN
SET NOCOUNT ON;
--INSTRUCCIN 1
--INSTRUCCIN 2
--INSTRUCCIN N
SET NOCOUNT OFF;
END
WHERE Campo
Tabla
Pgina 5 de 12
WHERE Campo
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
--INSTRUCCIONES 1,2N
END
O bien:
IF EXISTS (SELECT 1 FROM Tabla WHERE Campo
Condicionante)
BEGIN
--INSTRUCCIONES 1,2N
END
Pgina 6 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
9. Evada el uso de CURSORES
Los cursores son una herramienta usada para acceder y modificar
el resultado de una clusula SELECT fila por fila. El problema con
su uso es que consumen una enorme cantidad de recursos,
especialmente de memoria. Siempre que sea posible, se debe
omitir el uso de cursores o minimizar su implementacin. Algunas
alternativas y sustitutos al uso de cursores pueden ser:
Tablas temporales:
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
que sea posible en lugar de tablas temporales. Use estas ltimas
solo en caso de que se maneje una cantidad muy grande de
informacin y siempre procurando crear su estructura previamente
nunca crendolas al vuelo.
11.Implementacin de sql dinamico (o codigo rojo).
Aunque en general el uso de SQL Dinmico esta algo condenado
debido a que una mala implementacin puede resultar en un grieta
de seguridad que de entrada a un severo caso de SQL Injection.
La implementacin que se sugiere esta encapsulada dentro de un
procedimiento almacenado, no es del todo dinmica para la
aplicacin cliente, es decir, no le permite estructurar sentencias
libres y est orientada ms que nada a procedimientos
almacenados cuya funcin principal es una consulta parametrizada
con
opciones
variables.
Usare
la
base
de
datos
AdventureWorksDW2008R2 para ilustrar un ejemplo. Probaremos
con el siguiente procedimiento almacenado:
CREATE PROCEDURE BeforeRedCodeSELECT
(
@ProductKey INT=NULL,
@SalesOrderLineNumber TINYINT=NULL,
@OrderQuantity SMALLINT=NULL,
@CurrencyKey INT=NULL
)
AS
BEGIN
SET NOCOUNT ON
SELECT
FIS.ProductKey,
FIS.OrderQuantity,
FIS.UnitPrice,
FIS.SalesOrderNumber,
FIS.CurrencyKey,
FIS.SalesOrderLineNumber
FROM FactInternetSales FIS(NOLOCK)
WHERE FIS.ProductKey=ISNULL(@ProductKey, FIS.ProductKey)
AND FIS.SalesOrderLineNumber= ISNULL (@SalesOrderLineNumbe
r, FIS.SalesOrderLineNumber)
AND FIS.OrderQuantity= ISNULL (@OrderQuantity, FIS.OrderQu
antity)
AND FIS.CurrencyKey= ISNULL (@CurrencyKey, FIS.CurrencyKey
)
SET NOCOUNT OFF
END
Pgina 8 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
(
@ProductKey INT=NULL,
@SalesOrderLineNumber TINYINT=NULL,
@OrderQuantity SMALLINT=NULL,
@CurrencyKey INT=NULL
)
AS
BEGIN
SET NOCOUNT ON
DECLARE @Query AS NVARCHAR(MAX)
SET @Query=N'
SELECT
FIS.ProductKey,
FIS.OrderQuantity,
FIS.UnitPrice,
FIS.SalesOrderNumber,
FIS.CurrencyKey,
FIS.SalesOrderLineNumber
FROM FactInternetSales FIS(NOLOCK)
WHERE 1=1 '
IF @ProductKey IS NOT NULL
BEGIN
SET @Query = @Query + ' AND FIS.ProductKey = @ProductKey '
END
IF @SalesOrderLineNumber IS NOT NULL
BEGIN
SET @Query = @Query + ' AND FIS.SalesOrderNumber =
@SalesOrderLineNumber '
END
IF @OrderQuantity IS NOT NULL
BEGIN
SET @Query = @Query + ' AND FIS.OrderQuantity = @OrderQuantity
'
END
IF @CurrencyKey IS NOT NULL
BEGIN
SET @Query = @Query + ' AND FIS.CurrencyKey =@CurrencyKey '
END
--PRINT @Query
EXECUTE sp_executesql @Query
, N'@ProductKey INT, @SalesOrderLineNumber TINYINT,
@OrderQuantity SMALLINT, @CurrencyKey INT '
, @ProductKey = @ProductKey
, @SalesOrderLineNumber = @SalesOrderLineNumber
, @OrderQuantity = @OrderQuantity
, @CurrencyKey = @CurrencyKey
SET NOCOUNT OFF
END
Pgina 9 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
Pgina 10 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
penalizando el rendimiento en la base de datos al
ejecutar INSERT, UPDATES y DELETE.
Omita crear ndices con campos que contienen pocos valores,
como aquellos que son de tipo BIT o CHAR (de uno a cuatro) y
asegrese de no agregar el mismo ndice con distintos nombres.
El estudio profundo de la creacin, diseo y mantenimiento de
ndices escapa del alcance de este articulo (espero escribir algo
ms elaborado sobre el tema de ndices en un futuro), sin embargo
es importante que se tome el tiempo para comprenderlos. Su
correcta aplicacin puede favorecer por mucho el tiempo de
respuesta de sus consultas.
13.Recomendaciones adicionales:
Si
el
procedimiento
almacenado
contiene
demasiadas
sentencias IF-ELSE para ejecutar distintos procesos acorde a
ciertos parmetros, resulta ms eficiente separar cada bloque y
encapsularlos en procedimientos almacenados diferentes; Esto
para evitar que el plan de ejecucin cambie acorde al valor del
resultado de la expresin IF, desperdiciando con esto la ventaja de
el plan de ejecucin en memoria y la pre compilacin.
Evite el uso de la instruccin SELECT-INTO. Al ejecutarse se
bloquean las tablas involucradas. Aplique en su lugar la
sentencia INSERT INTO-SELECT.
Trate de usar siempre la instruccin JOIN antes que cualquier sub
consulta.
Use la instruccin BETWEEN en lugar de IN siempre que sea
posible.
En el caso de que se use la instruccin LIKE, evite el uso del
comodn % al inicio de la cadena a buscar. Esto debido a que si
se aplica, la bsqueda tendra que leer todos los datos de la tabla o
tablas involucradas para responder a la consulta. Se recomienda
que existan al menos tres caracteres antes del comodn.
Evite en la medida de lo posible el uso de DISTINCT
En caso de usar la instruccin UNION y existiera la seguridad de
que en los SELECT involucrados no se obtendrn registros
duplicados, entonces lo recomendable en este escenario es
sustituir UNION por UNION ALL para evitar que se haga uso
implcito de la instruccin DISTINCT, ya que esta aumenta el
consumo de recursos.
Evada siempre que sea posible el uso de ORDER BY. Al igual
que DISTINCT consume una elevada cantidad de recursos.
Considere si es realmente necesario usarlo o, si por otro lado se
puede dejar el ordenamiento de los resultados a la aplicacin que
recibir los datos.
Use SQL Profiler y levante una traza para estudiar el rendimiento
de los procedimientos almacenados de mayor concurrencia y vea
opciones para refactorizar el proceso. Otorgue especial atencin a
las columnas CPU, Duraction,reads y writes para optimizar el
uso de memoria y el I/O generado.
Mantenga las transacciones lo ms cortas posibles dentro de un
procedimiento almacenado. Esto favorece a la reduccin del
nmero de bloqueos, promoviendo a acelerar el rendimiento
general de la base de datos.
Pgina 11 de 12
montana.com.pe
Buenas Prcticas Base de Datos SQL Server
Pgina 12 de 12