Ver Mensaje Individual
  #6  
Antiguo 07-09-2010
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.912
Reputación: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Básicamente cualquier motor de datos tiene un buen sistema de manejo de indices y mas si es de gama medio o alta (sql server, oracle, postgress, etc).

Algunas ideas generales:

http://www.sql-server-performance.co...eneral_p1.aspx

Si necesitas ver que pasa con un indice usas el Sql profiler & el Index Tuning Wizard.


Primero que nada, no te pongas a agregar indices a la loca.

Un indice es como una tabla extra. Aumenta la CPU, el acceso I/O e implica hacer saltos entre los indices y la tabla fisica. Un numero excesivo de indices puede tener un impacto negativo.

Pero mas que nada, la eficiencia es en *como* almacenas los datos. El indice es solo una ayuda auxiliar. De hecho, a veces es posible que un indice de un resultado adverso o inutil (ej: Indexar sobre un campo booleano, donde casi al 50% uno es 0 y el otro es 1: No sirve pa nada de nada el indice).

Lo que debes saber es que existe una regla: optimizas por espacio, o por velocidad.

La forma de acelerar las consultas es expandir el dataset. Una BD es *muy* feliz si los datos se los dan mascaditos y lo unico que debe hacer es recorrer de arriba a abajo, saltando por medio de inidices sobre datos de longitud fija. Esa es el mejor caso.

Un ejemplo clasico son las fechas.

Una fecha se almacena por ejemplo asi: 01/01/2010. Ahora necesitas buscar los registros del año 2010. lo normal, una funcion tipo YEAR(fecha).... lo cual mata el indice (= no se usa!).

La forma de acelerar es partir la fecha en 3 columnas: Año, mes, dia e indexar si los cambios en cada una son variables... O sea, si en Año solo hay 2010, 2011 meter indice puede ser casi inutil.

En tal caso, mete los datos preordena los datos.. en vez de :

2011
2010
2011

Que esten

2010
2011
2011

(Eso es en Sql server un indice *clustered*).

En mi aplicacion de iphone, donde existen recursos mas limitados de CPu/Memoria ese solo cambio logro que una consulta pasara de unos 5-10 segundos a milisegundos. Sin meter indices!!

Otro ejemplo?

Otro cambio que me bajo de 10 segundos a milisegundos: Ordenar/Buscar por nombre.

Supongamos que debemos buscar todos los nombres que empiezan por 'A'. Supongase que existen 100 registros que cumplen, de 1 millon en total.

La forma pendeja es - pero practica en la gigantesca mayoria de los casos-:

Código SQL [-]

WHERE Left(Nombre,1)='A'

o

WHERE Nombre Like 'A%'

Dependiendo del motor, es una busqueda de 1 millon de registros.

Sin embargo, es mas eficiente si agregas una columna llamada IndexName y que guardas la primera letra. Ahora queda asi:



Código SQL [-]

WHERE  IndexNombre='A' AND Left(Nombre,1)='A'

o

WHERE IndexNombre='A' AND Nombre Like 'A%'

En *cualquier* motor, es una busqueda de 100 registros.

Eso acorta la consulta porque:

1) De entrada se filtra a solo lo que empieza por A en IndexNombre
2) Luego, la BD busca de esa porcion, el nombre

La gracia del truco se ve si Buscas por 'Alfo' para encontrar 'Alfonso'.

Ahora, primero se limita la busqueda a 100 registros y sobre ellos, se hace un table scan pa encontrar los 5 o 10 que sean alfonso.

----

En resumen, no es solo indices. Si quieres maximizar la eficiencia, es *como* almacenas los datos.

Mientras mas *plano* (menos funciones, menos joins, filtrar de izq a derecha lo mas global a lo mas concreto -o al revez, no se su es igual en cada motor).
__________________
El malabarista.
Responder Con Cita