Anda di halaman 1dari 13

PRI VADO

ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 1-1/13

ESTNDARES DE SQL
HIPER S.A.
V2.00-050208

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 2/13

Rol Preparado por: Revisado por: Aprobado por:


Analista Encargada de Procesos Gerente de Desarrollo de Software

Autor
Roberto Salazar Susana De la Cruz lvaro Chavez

Fecha
09-04-2010

Resumen :

Procedimiento para estndares de programacin SQL en el rea de desarrollo.

EVOLUCIN DEL DOCUMENTO


Versin Draft 1.00 1.10 1.20 Fecha 08/04/2010 09/04/2010 12/04/2010 13/04/2010 Autor Achavez Rsalazar Rsalazar Rsalazar Evolucin Reunin de trabajo, primera versin Complementar los acuerdos de la reunin de trabajo Incorporar observaciones de lvaro Chvez. Incorporar observaciones de lvaro Chvez. Incluir comentario sobre el uso de campos VARCHAR en el diseo de tablas. 1.30 14/04/2010 Rsalazar Ampliar la descripcin del TIMEOUT en el diseo de aplicaciones.

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 3/13

CONTENIDO

1 1.1 1.2 1.3 2 2.1 2.2 2.3 3 3.1 3.2 3.3 3.4 3.5 4 4.1

INTRODUCCIN .............................................................................................. 4 OBJETIVO ...................................................................................................... 4 AUDIENCIA .................................................................................................... 4 DOCUMENTOS DE REFERENCIAS .............................................................. 4 RECOMENDACIONES PARA DISEO ............................................................ 5 DISEO DE APLICACIONES ......................................................................... 5 DISEO DE TABLAS ..................................................................................... 6 DISEO DE INDICES .................................................................................... 7 RECOMENDACIONES PARA EL DESARROLLO DE SQL ............................. 8 CAMPOS ........................................................................................................ 8 TABLAS.......................................................................................................... 9 FILTROS ........................................................................................................ 9 ORDEN ........................................................................................................ 12 GRUPOS ...................................................................................................... 12 ANEXOS ......................................................................................................... 13 ANEXO 1 DISEO DE INDICES EN SQL SERVER 2005 ............................ 13

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 4/13

1 INTRODUCCIN
1.1 OBJETIVO

Una sentencia SQL mal diseada y/o desarrollada puede afectar seriamente la performance de la base de datos aumentando considerablemente los tiempos de respuesta, este documento contiene recomendaciones para evitar que el HIPERCENTER se vea afectado por esta contingencia y pueda ser un producto escalabre a administrar millones de transacciones en una misma base de datos. Cuando se ejecuta una sentencia SQL es el gestor de Base de Datos el que interpreta y optimiza el cdigo entregado, este documento contiene en su mayora recomendaciones que pueden ser aplicadas en diferentes base de datos : SQL Server, MySql, ORACLE.

1.2

AUDIENCIA

El presente documento esta dirigido a: Los lderes de proyectos Los programadores responsables por el mantenimiento y desarrollo de los diferentes sistemas. A las personas involucradas en la revisin de las fuentes y la determinacin de la calidad de los mismos.

1.3

DOCUMENTOS DE REFERENCIAS

El documento inicial ha sido la presentacin HIP-SQLServer-Mejoras-Rendimiento-01 enviada por Lus Hernndez.

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 5/13

RECOMENDACIONES PARA DISEO

Para prevenir problemas de performance se requiere seguir estas recomendaciones en el diseo de: tablas, aplicaciones e ndices. Algunas base de datos como SQL Server 2005 tienen implementado herramientas para el diseo y la gestin de ndices que estn detalladas en el ANEXO 1.

2.1
1

DISEO DE APLICACIONES
Recomendacin Las sentencias SQL no se ponen en los programas. Deben estar en un paquete de objetos DB. Descripcin Para evitar que una sentencia SQL impacte en la performance de los aplicativos se restringe su uso en los programas. Todos los accesos a la Base de Datos deben estar en el paquete Objetos DB o equivalente, uno genrico (Como HIPERCENTER) y uno por aplicacin (Como HERMES, PROCESOS MC). Ejemplo

No deben crearse sentencias SQL redundantes.

En algunos casos se generan sentencias SQL por filtros adicionales a pesar que los que existen estn suficientemente acotados. Ejemplo: Cuando se busca una transaccin que debe estar vigente y/o ser de tal tipo, si existe un SQL que permite obtener la transaccin con el nmero, la validacin del estado de vigencia y el tipo debe realizarse a nivel aplicacin. Recibir como parmetro parte de la sentencia SQL no es lo ms adecuado.

No deben crearse funciones que reciban fragmentos de la sentencia SQL como parmetro. Controlar el TIMEOUT en todas las sentencias SQL

Las sentencias SQL deben tener un tiempo mximo de ejecucin. Establecer el tiempo mximo que una instruccin esperar a un recurso bloqueado, la aplicacin debe tener un controlador de errores que pueda interceptar el mensaje de bloqueo y decidir si se reenva la instruccin bloqueada o se revierten las transacciones. La sentencia Select count (*) hace un SCAN completo de la tabla, se puede usar una va alternativa usando las tablas del sistema.

Evitar el uso del select count (*) para obtener el total de registros de una tabla.

SQL correcto select B.rows from sys.tables A, sys.sysindexes B where

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 6/13
A.name = 'tpTransactionLog' and B.indid < 2 and A.object_id = B.id SQL incorrecto select count(*) from dbo.tpTransactionLog

2.2
1

DISEO DE TABLAS
Recomendacin Normalizar las tablas Descripcin Para evitar que existan campos con informacin duplicada, se deben normalizar las tablas al menos hasta la tercera forma normal. Si se tiene conocimiento de la longitud mxima de un campo carcter se debe definir como CHAR. Usar datos de longitud variable ( VARCHAR) cuando el tamao de las cadenas varia considerablemente como en campos de : direccin, descripcin es, observaciones, etc. Las campos de longitud fija: integer, char, date se ponen al inicio de la tabla los de longitud variables: varchar se ponen al final. Si los campos de longitud variable son muy grandes es preferible ponerlos en otra tabla compartiendo la PK. Ejemplo

Evitar el uso de campos de longitud variables (VARCHAR).

Diseo Correcto cTxType char(2) Diseo Incorrecto cTxType varchar(2)

En una tabla primero se definen los de longitud fija y despus los de longitud variable.

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 7/13

2.3

DISEO DE INDICES
Recomendacin No crear ndices Redundantes Descripcin Los ndices ocupan mucho espacio en disco, adems cuando se insertan o actualizan los registros de una tabla se requiere tiempo adicional para actualizar los ndices. Antes de crear nuevos ndices se debe revisar los ya existentes y evaluar si amerita crear uno adicional. El costo de tener ndices que no se usan es: Mayor tiempo de respuesta en las actualizaciones, Mayor tiempo en obtener las copias de seguridad. Ejemplo La tabla tpTransactionLog tiene estos ndices : IX_ANULA_REVERSA cTxMerchantId cTxTerminalNum cTxBatchId IX_REPORTE cTxMerchantId cTxTerminalNum cTxBatchId cTxType cTxAplicacion TX_CONSULTA_TRANSACCIONES nTxGenCounter PK_tpTransactionLog nTxGenCounter IX_NUMERO_REGISTROS nTxGenCounter fTxTxnDate hTxTxnHour cTxAplicacion cTxMerchantChain Los campos del ndice IX_ANULA_REVERSA estn contenidos en IX_REPORTE, incluso tienen el mismo orden. El ndice debe ser el mas pequeo posible, debe tener la granularidad necesaria, debido a que muchas transacciones tienen el mismo cdigo de aplicacin y el mismo tipo de transaccin el ndice IX_ANULA_REPORTE no aade valor, es Redundante. El ndice TX_CONSULTA_TRANSACCIONES tiene los mismos campos de la llave primaria, es Redundante.

Crear ndices pequeos de longitud fija y mnima

Los campos de la llave primaria (PK) deben ser del menor tamao posible, usar de preferencia campos del tipo: SMALLINT, INTEGER, CHAR en ese orden. No usar campos de tipo VARCHAR en los ndices. Cuanto ms grande sea la clave, menos filas se pueden almacenar en las pginas de ndice, haciendo que haya un mayor nmero de niveles de rbol binario; como consecuencia, para llegar a una fila especfica se deben realizar ms operaciones de Entrada/Salida.

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 8/13

3 RECOMENDACIONES PARA EL DESARROLLO DE SQL


Estas recomendaciones se clasifican segn la clusula del SQL en: Campos, para la relacin de campos que se ponen despus del SELECT Tablas, para la relacin de tablas que se ponen despus del FROM Filtros, para las expresiones lgicas que se ponen despus del WHERE. Orden, para la relacin de campos que se ponen despus del ORDER BY Grupos, para la relacin de campos que se ponen despus del GROUP BY

3.1
1

CAMPOS
Recomendacin No utilizar nunca SELECT * Descripcin Seleccionar exclusivamente aquellos que se necesiten. El gestor BD lee primero la estructura de la tabla para extraer las columnas y luego ejecuta la sentencia. Ejemplo SQL Correcto select cTrMerchantId,cTrTerminalNum, dTrTerminalSN from dbo.tmTerminal SQL Incorrecto Select * from dbo.tmTerminal SQL Correcto select cTrMerchantId,cTrTerminalNum, dTrTerminalSN from dbo.tmTerminal WITH (NOLOCK) SQL Correcto select A.cUsuario,B.dRolNombre from dbo.tmUsuario A, dbo.tmRol B, dbo.taUsuarioRol C WITH (NOLOCK) where A.cUsuario = 'U000004' and A.cUsuario = C.cURUsuario and B.cRol = C.cURRol SQL Incorrecto select cUsuario,dRolNombre from dbo.tmUsuario , dbo.tmRol , dbo.taUsuarioRol WITH (NOLOCK) where cUsuario = 'U000004' and cUsuario = cURUsuario and cRol = cURRol

Al utilizar una instruccin SELECT, especifique la sugerencia NOLOCK para evitar que se bloqueen las otras aplicaciones. En una consulta de varias tablas especificar a que tabla pertenece cada columna

Una instruccin SELECT puede provocar bloqueos por defecto.

Le ahorras al gestor BD el tiempo de localizar a que tabla pertenece el campo.

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 9/13

3.2
1

TABLAS
Recomendacin En la clusula FROM deben ir primero las tablas que tienen campos de filtro en el WHERE. Descripcin En una consulta con mltiples tablas el gestor BD inicia el pareo de las filas con la primera tabla especificada en la clusula FROM, si la tabla que tiene filtros esta primero el gestor BD tendr menos filas que parear con las otras tablas. Ejemplo SQL Correcto select A.cTxMerchantId , A.cTxTerminalNum , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxMerchantId = '299999490000' and A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion SQL Incorrecto select A.cTxMerchantId , A.cTxTerminalNum , B.dTTTransactionName from dbo.tmTransactionType B, dbo.tpTransactionLog A where A.cTxMerchantId = '299999490000' and A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion

Para unir las filas de varias tablas, usar UNION ALL en vez de UNION

La declaracin UNION ALL es ms rpida que la declaracin UNION, esta ultima busca si existen filas duplicadas.

3.3
1

FILTROS
Recomendacin No usar la clusula IN Descripcin La clusula IN se puede sustituir por dos o mas expresiones lgicas unidas por el conector OR Ejemplo SQL Correcto select A.cTxMerchantId , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxMerchantId = '299999490000' and (B.dTTTransactionName = 'CC_RELACION_CUENTAS' or B.dTTTransactionName = 'CC_CONS_TARJETA' ) and A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion SQL Incorrecto select A.cTxMerchantId , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 10/13
A.cTxMerchantId = '299999490000' and B.dTTTransactionName in ('CC_RELACION_CUENTAS','CC_CONS_TARJETA') and A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion SQL Correcto select cUsuario from dbo.tmUsuario where cUsuario LIKE 'MC%' SQL Incorrecto select cUsuario from dbo.tmUsuario where cUsuario LIKE '% MC'

No usar el operador LIKE.

Esta es una lista ordenada de operadores de mejor a peor rendimiento : = >, >=, <, <= LIKE <> Si el uso del operador LIKE es inevitable, el carcter comodn (wildcard) debe ponerse despus de los caracteres principales (leading carcter). Si el comodn se pone al inicio se hace un SCAN completo de la tabla. El uso de funciones impide que el gestor BD use los ndices de la tabla. Se podra generar ndices usando funciones pero no es recomendable. La versin que tiene mejor rendimiento es la primera y la ltima es la que peor rendimiento tiene.

No usar funciones en la clusula WHERE

SQL Incorrecto select dTrTerminalSN from dbo.tmTerminal where SUBSTING(cTrMerchantId,1,2) = '23'

Para filtros con SUB QUERYS usar la clusula NOT EXISTS. No usar la clusula NOT IN

SQL correcto, usando NOT EXISTS SELECT a.hdr_key FROM hdr_tbl a WHERE NOT EXISTS (SELECT * FROM dtl_tbl b WHERE a.hdr_key = b.hdr_key) SQL Incorrecto, usando LEFT JOIN SELECT a.hdr_key FROM hdr_tbl a LEFT JOIN dtl_tbl b ON a.hdr_key = b.hdr_key WHERE b.hdr_key IS NULL SQL Incorrecto, usando NOT IN SELECT hdr_key FROM hdr_tbl WHERE hdr_key NOT IN (SELECT hdr_key FROM dtl_tbl) Tabla tmTerminal PK de la tabla cTrMerchantId cTrTerminalNum SQL Correcto select dTrTerminalSN from dbo.tmTerminal where cTrMerchantId = '232994890000' and cTrTerminalNum = '0005'

En la clusula WHERE poner los campos que formen parte de la llave primaria (PK). Adems se deben especificar en el orden en el que estn definidos en la PK.

Al existir un ndice con los campos de la PK, cuando se usan los campos de la PK en la clusula WHERE se acelera considerablemente las bsquedas. En general en el WHERE se deben usar los campos que tengan ndices y se deben especificar en

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 11/13
el orden en el que estn definidos en el ndice.

En una consulta con mltiples tablas, los filtros especficos a las tablas deben ir primero, los joins deben ir despus.

El gestor BD recupera primero las filas de los filtros y luego las parea con las otras tablas.

SQL Incorrecto select dTrTerminalSN from dbo.tmTerminal where cTrTerminalNum = '0005' and cTrMerchantId = '232994890000' SQL Correcto select A.cTxMerchantId , A.cTxTerminalNum , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxMerchantId = '299999490000' and A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion SQL Incorrecto select A.cTxMerchantId , A.cTxTerminalNum , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion and A.cTxMerchantId = '299999490000' SQL correcto select cTxMerchantId, nTxGenCounter,cTxType from dbo.tpTransactionLog where cTxMerchantId = '299999490000' and fTxTxnDate >= '20100325' and fTxTxnDate <= '20100330' and cTxType = '70' SQL Incorrecto select cTxMerchantId, nTxGenCounter,cTxType from dbo.tpTransactionLog where cTxMerchantId = '299999490000' and cTxType = '70' and fTxTxnDate >= '20100325' and fTxTxnDate <= '20100330' En el ejemplo para un comercio existen muchas transacciones del tipo 70 y hay menos transacciones entre las fechas, por este motivo la expresin lgica de las fechas debe ponerse primero.

En expresiones lgicas unidas por dos o ms operadores AND localizar la expresin menos probable de suceder y ponerla en primer lugar.

El gestor BD evala las expresiones lgicas de izquierda a derecha Localizar la expresin menos probable de suceder y ponerla en primer lugar de la expresin AND, de este modo si una expresin AND es falsa la clusula finalizar inmediatamente ahorrando tiempo. Si las expresiones son iguales o tienen igual peso, y son falsas, pondremos la menos compleja primero. De este modo si es expresin es falsa se realizar menos trabajo para evaluarla. Si todas expresiones son Verdaderas debe poner primero la que obtenga menos filas y luego la que obtenga

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 12/13
mayor numero de filas.

3.4
1

ORDEN
Recomendacin No usar la clusula ORDER BY Descripcin Realizar el ordenamiento en el lado del cliente. Ejemplo SQL Correcto select A.cTxMerchantId , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxMerchantId = '299999490000' and A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion

SQL Incorrecto select A.cTxMerchantId , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxMerchantId = '299999490000' and A.cTxType = B.cTTTransactionId and A.cTxAplicacion = B.cTTAplicacion ORDER BY B.dTTTransactionName

3.5
1

GRUPOS
Recomendacin Restringir el uso de la clusula GROUP BY Descripcin Si se trata de un grupo pequeo e filas se puede realizar el agrupamiento en el lado del cliente. Si es inevitable el uso de la clusula GROUP BY, por que es una gran cantidad de informacin se deben poner campos que tengan ndices. Ejemplo SQL Correcto select A.cTxMerchantId , B.dTTTransactionName from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxMerchantId = '299999490000' SQL Incorrecto select A.cTxMerchantId , B.dTTTransactionName, ,count(*) from dbo.tpTransactionLog A, dbo.tmTransactionType B where A.cTxMerchantId = '299999490000' GROUP BY A.cTxMerchantId, B.dTTTransactionName

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

PRI VADO
ESTNDARES DE SQL

VERSIN 1.30
FECHA:14/04/2010

Pgina 13/13

4 ANEXOS
4.1 ANEXO 1 DISEO DE INDICES EN SQL SERVER 2005
Recomendacin Usar las vistas de administracin dinmica (DMV) para identificar los ndices que no se estn utilizando. Descripcin El SQL Server 2005 tiene vistas de administracin dinmica (DMV) que permiten el acceso a una gran cantidad de informacin sobre cmo el servidor SQL esta usando los recursos , se puede usar la vista dinmica (DMV) sys.dm_db_index_usage_stats para identificar los ndices que no se estn usando. Se puede consultar estas DMV para identificar los ndices que faltan: sys.dm_db_missing_index_details sys.dm_db_missing_index_group_stats sys.dm_db_missing_index_groups sys.dm_db_missing_index_columns Ejemplo

Usar DMV para identificar los ndices que faltan.

NOTA: La informacin contenida en este documento no puede ser duplicada, publicada o copiada sin permiso escrito de HIPER S.A.

Anda mungkin juga menyukai