Está en la página 1de 2

:: LAD - Linux a Distancia :: file:///I:/CURSO PHP/CLASE 019.

htm

Aumentando la velocidad de acceso


Cuando se esta trabajando con tablas que poseen pocos registros, no es posible notar si el
sistema tiene o no una buena performance. De movida, con cada SELECT que se ejecuta se
deberá barrer todos los registros de la tabla para encontrar aquellos que concuerden con el
criterio pedido. Al aumentar la cantidad de registros el sistema comienza a volverse más y
más lento, aún para las consultas más sencillas. Esto ocurre ya que para realizar una
búsqueda, el motor necesariamente necesita recorrerse toda la tabla (FULLSCAN) para
verificar que registros concuerdan.
Esta situación puede y debe ser remediada haciendo uso de índices. Un índice es una
estructura auxiliar la cual ayuda a encontrar registros sin necesidad de hacer un barrido
completo de la tabla. Existen varios tipos de índices pero actualmente, MySQL soporta solo un
tipo: el Arbol-B.
Los índices se crean sobre una o más columnas de una tabla. Esto implica que toda esa
información estará "duplicada", o sea, que el índice ocupará un espacio un poco mayor al
tamaño total de las columnas seleccionadas. Al usar el índice se aumentará la velocidad al
tratar de recuperar registros en base a esas columnas pero tendrá el costo de actualizarse
cuando se inserta o borra una fila. Es por eso que los índices pueden ser beneficiosos pero si
se usan en exceso pueden llegar a no serlo.

Un Arbol-B es una estructura que posee forma de árbol que crece de la raíz hacia la hojas. En
un arból habrá un nodo raíz el cuál tendrá N hijos. A su vez cada hijo de la raíz puede tener N
hijos y así sucesivamente. A cada camino que se va formando se lo llama rama. Aquellos
nodos que se encuentren al final de cada rama se los denomina hoja.
Si se arma un Arbol-B sobre una columna, por ejemplo CODIGO de la tabla CLIENTES, en
promedio para buscar un CODIGO en una tabla de 1.000.000 de registros, tomará 20 accesos.
Este valor es mucho menor a barrerse el millón de registros.

Los índices se crearán sobre las columnas en las cuales hagamos consultas frecuentemente.
Por lo expuesto anteriormente, no es beneficioso poner índices en todas las columnas. Por lo
tanto, habrá que analizar que consultas se harán y en donde conviene crear los índices.
Internamente, MySQL, al determinar una(s) columna(s) como clave primaria, generará un
índice único sobre dichas columnas. Por lo tanto, sobre la clave primaria siempre se tiene
buena velocidad de acceso. Esto se debe a que las relaciones siempre se hacen sobre las
claves primarias por lo tanto si no se posee dicha columna indexada tomará mucho tiempo
relacionar dos tablas.

Los índices pueden o no aceptar valores duplicados. Si creamos un índice único, entonces los
valores de esa columna nunca se repetirán. Cuando utilizabamos el UNIQUE en el CREATE
TABLE, lo que se creabá era un índice que aseguraba esto.
Una vez creado el índice MySQL se encargará automaticamente de determinar cuando
conviene utilizarlo y cuando no. Por lo tanto, no hará falta en cada consulta escribir
explicitamente que índice debe usar ni como.

En MySQL para crear un índice se utilizará el comando:

CREATE [UNIQUE] INDEX nombre_indice ON tabla ( campos )

En donde, la palabra UNIQUE es opcional y determina si el índice aceptará o no aceptará


duplicados.
nombre_indice es simplemente el nombre que se la dará al indice (para poder eliminarlo
luego si hace falta).
tabla es el nombre de la tabla sobre la cual se creará el índice.
Y campos son todos los campos (1 o más) que tomará el índice. Si se necesitan más de un
campo se los debe separar por comas.

Una vez creado el índice es posible eliminarlo si hace falta. Para ello se utlizará el comando
DROP INDEX de la siguiente forma:

DROP INDEX nombre_indice ON tabla

En donde, nombre_indice es el nombre que se le dió al indice cuando se creo y tabla es el


nombre de la tabla sobre la cual esta el índice.

Integridad Referencial
Cuando comenzamos a hablar de base de datos hicimos mención de la integridad
referencial. La integridad referencial significa poder decirle al motor explícitamente que
campo hace referencia a que clave primaria de que tabla. Por lo tanto, tendriamos las
relaciones metidas dentro del motor(reglas de integridad), lo cual nos asegura que la base
siempre esta en un estado consistente. Esto significa que nunca encontraríamos relaciones
mal hechas o códigos que no existen.
Las tablas estandar (MyISAM) no pueden utilizar integridad referencial. Para ello hay que crear
las tablas del tipo InnoDB como hemos visto en clases anteriores (utilizando la opción TYPE en
el CREATE TABLE). Además existe otra restricción: para crear una relación ambas columnas, la
clave foránea como la clave referenciada, deben tener un índice creado. Esto se debe a que en
el caso contrario, la performance disminuiría significativamente con cada INSERT, DELETE y
UPDATE ya que las reglas de integridad se deben verificar en cada una de estas operaciones.
Para definir una relación entre dos tablas utilizaremos la sentencia ALTER TABLE de la
siguiente forma:

ALTER TABLE tabla

1 de 2 29/07/2011 03:45 p.m.


:: LAD - Linux a Distancia :: file:///I:/CURSO PHP/CLASE 019.htm

tabla
ADD [CONSTRAINT nombre_constraint] FOREIGN KEY (columnas_clave_foranea)
REFERENCES tabla_independiente (columnas_independiente

[ ON DELETE CASCADE | SET NULL | NO ACTION | RESTRICT ]


[ ON UPDATE CASCADE | SET NULL | NO ACTION | RESTRICT ]

Aquí tabla es la tabla que posee una columna que es clave foránea. Esta es la columna que
hará referencia a otra tabla.
nombre_constraint es el nombre que se le dará a la relación. Esta alternativa (es opcional)
existe simplemente para respetar el estándar ya que MySQL la ignora.
columnas_clave_foranea son el nombre de la o las columnas (separadas por comas) que
hacen referencia a la tabla independiente.
tabla_independiente es la tabla la cual es referenciada y columnas_independientes su clave
primaria (que deberán concordar con las de columnas_clave_foranea).

Antes de ver las otras opciones veamos un ejemplo:

CREATE TABLE CLIENTES (


CES_ID INT UNSIGNED NOT NULL,
CES_RAZON_SOCIAL VARCHAR(50) NOT NULL,
CES_DIRECCION VARCHAR(100) NOT NULL
) TYPE=InnoDB;

ALTER TABLE CLIENTES ADD PRIMARY KEY (CES_ID);

CREATE TABLE VENTAS (


VAS_NUMERO INT UNSIGNED NOT NULL,
VAS_CES_ID INT UNSIGNED NOT NULL,
VAS_FECHA DATETIME NOT NULL,
VAS_MONTO_TOTAL DECIMAL(13,2) NOT NULL,
) TYPE=InnoDB;

ALTER TABLE VENTAS ADD PRIMARY KEY (VAS_NUMERO);

CREATE INDEX NDX_CLIENTES ON VENTAS (VAS_CES_ID);

ALTER TABLE VENTAS ADD FOREIGN KEY (VAS_CES_ID) REFERENCES CLIENTES (CES_ID);

En este ejemplo, CLIENTES es la tabla independiente. Además su clave primaria esta


compuesta por la columna CES_ID. Por lo tanto, toda tabla que haga referencia a un cliente,
debe poner el código de esta columna. VENTAS es la tabla que hace referencia a un cliente. Por
lo tanto se definió una columna, VAS_CES_ID, que contendrá el código del cliente que realizó la
operación. Como será una clave foránea se creó un índice sobre la misma. Luego, el ALTER
TABLE correspondiente relaciona la columna VAS_CES_ID de la tabla VENTAS con la columna
CES_ID (clave primaria) de la tabla CLIENTES.

Como recomendación práctica diremos que es mejor, dentro del script que generá la base de
datos, definir primero todas las tablas y luego todas las relaciones. De esta forma siempre que
se vaya a definir una relación ya se poseen las tablas intervinientes creadas y no hay que
estar moviendo definiciones por todo el archivo para que al momento de definir la relación
ambas tablas existan.

Por último veamos las opciones restantes ON DELETE y ON UPDATE. Esta reglas le dicen al
motor que hacer en caso que se borre o actualice el valor de la clave referenciada (en el
ejemplo CES_ID de CLIENTES). Hay 4 acciones posibles: CASCADE, SET NULL, NO ACTION y
RESTRICT. Las acciones son similares para DELETE y UPDATE con la única diferencia que DELETE
borrará y UPDATE actualizará.
La opción CASCADE propagará la operación a las tablas referenciadas. En el ejemplo, si
borramos un cliente se borrarán de la tabla VENTAS todos los registros que contengan a ese
cliente.
La alternativa SET NULL pondrá el valor NULL en la columna de la clave foránea (VAS_CES_ID)
si y solo si la columna acepta valores nulos. Si no los acepta no se podrá realizar la operación
(el DELETE o UPDATE fallarán).
La opción NO ACTION (no recomendada) no tomará ninguna acción y la base quedará en un
estado inconsistente.
Finalmente, la opción RESTRICT prohibirá la ejecucíon del DELETE o del UPDATE y nunca podrá
ser eliminada o actualizada la clave primaria de la tabla independiente.

Ejercicios
1. ¿Para que se utilizan los indices?
2. ¿Que ventajas trae utilizar indices?
3. ¿Que desventajas trae utilizar indices?
4. Se pide agregar todas las reglas de integridad referencial a la agenda creada
anteriormente.
5. Se pide agregar todas las reglas de integridad referencial al sistema generado a
voluntad.

2 de 2 29/07/2011 03:45 p.m.

También podría gustarte