Ayuda con indices en base de datos

Iniciado por Skeletron, 25 Octubre 2009, 22:22 PM

0 Miembros y 1 Visitante están viendo este tema.

Skeletron

Hola señores..
Les comento que tengo una aplicacion, que al ahcer click en un CALENDARIO, aparecen los datos de las "transacciones" realizadas ese dia... (algo así)
Es como que, en la base de datos, hay unas 50 entradas por cada dia de cada mes..
Entonces para agilizar la busqueda me recomendaron crear INDICES...

Si tengo entradas con los sigueintes valores (columnas): "MES(integer)" "DIA(integer)" "TEXTO(Varchar(200))" "VERSION(integer)"
Yo hago selects del tipo: SELECT Texto FROM Tabladedatos Where Mes = 'xx' and Dia = 'xx'

Me recomienda colocar un indice en Mes? en Dia? o en Ambos?

Novlucker

Y puede que hayan muchos registros? Porque en realidad para una tabla con pocos datos y esos cuatro atributos no te hará mucha diferencia :P

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Skeletron

Abrá aproximadamente 18.500 registros...

Novlucker

A mi realmente no me parece muy necesario, después de todo la búsqueda es por medio de dos integers  :P

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein

Skeletron


^Tifa^

Si lo veo extremadamente necesario, sobretodo porque hoy son 18,500 registros y en semanas o meses podria ser el duplicado.

Si no tienes indices y buscas X dato en una tabla, es como si tuvieras un libro de 1,000 paginas con informacion de lado y lado por pagina, y yo te diga Skeletron buscame en el libro algo sobre 'tecnologia actual' y tu tengas que empezar hoja, por hoja, por hoja a buscarme (digamos que tu libro no tiene indice) sin embargo si tu libro tiene un indice delante que dice los temas y subtemas por paginas, no seria mas eficiente para ti y mas rapido y menos perdida de tiempo por lo menos saber que en la pagina X hay info sobre 'tecnologia actual' que ir hojeando hoja, por hoja, por hoja ???

Esto aplicalo a nivel de un programa en un PC, en este caso la base de datos, hace lo mismito, empieza a buscar la info en las tablas y esto es lectura del HD buscando un dato..... imaginate 20 usuarios a la vez buscando distintos datos en la misma tabla sin indices... y leyendo y leyendo en tu HD buscando ahi...

Como indice podria recomendarte un ID o algo similar, es que si te digo DIA o MES muchos registros podrian tener el mismo DIA y el mismo MES cuando tu solo quieres la info de 1 solo registro por ejemplo. Aun estas a tiempo de alterar la tabla y agregarle un campo ID por registro, y hacer un bucle en tu lenguaje que llene ese campo ID desde 1 hasta 18,500 para que asi cada registro tenga su correspondiente ID y te sea mas facil la busquedad con Indices

^Tifa^

#6
De hecho como soy un poco pesima exponiendome, lo hago mas visual:

Tengo 1 simple tabla con 3 datitos:

Código (sql) [Seleccionar]


mysql> select * from ejemplo;
+------+------+--------+     
| dia  | mes  | nombre |     
+------+------+--------+     
|    1 |   11 | Maria  |
|    1 |   10 | Juan   |
|    2 |    9 | Pedro  |
+------+------+--------+
3 rows in set (0.00 sec)



No tengo indices como tu. Asi que hago una mera consulta sencilla:

Código (sql) [Seleccionar]


mysql> select * from ejemplo where dia = 1;
+------+------+--------+
| dia  | mes  | nombre |
+------+------+--------+
|    1 |   11 | Maria  |
|    1 |   10 | Juan   |
+------+------+--------+
2 rows in set (0.00 sec)




Todo bien? visualmente si.... ahora veamos como el motor analiza en verdad el asunto de busquedad en el disco, usemos la herramienta de preferencia EXPLAIN (para tunnings en base de datos)

Código (sql) [Seleccionar]


-mysql> explain select * from ejemplo where dia = 1;
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | ejemplo | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)                                                                           

mysql> explain select * from ejemplo where dia = 1 and mes = 11;
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | ejemplo | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
+----+-------------+---------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)





Fijate la parte donde dice:  rows - 3  (como no tengo indices definidos en mi tabla, aunque haga la busquedad por una constante dia = 1 el motor de la DB debe buscar en todos los registros para dar con la ubicacion de ese registro, en este caso recorrio todos los datos de mi tabla que son apenas 3.... en tu caso serian 18,500 registros a recorrer antes de devolverte donde esta el valor).

Ahora creo un indice en mi tabla:

Código (sql) [Seleccionar]


mysql> create index indice on ejemplo(dia);
Query OK, 3 rows affected (0.05 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> explain select * from ejemplo where dia = 1;
+----+-------------+---------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table   | type | possible_keys | key    | key_len | ref   | rows | Extra       |
+----+-------------+---------+------+---------------+--------+---------+-------+------+-------------+
|  1 | SIMPLE      | ejemplo | ref  | indice        | indice | 5       | const |    1 | Using where |
+----+-------------+---------+------+---------------+--------+---------+-------+------+-------------+
1 row in set (0.01 sec)

mysql> explain select * from ejemplo where dia = 3;
+----+-------------+---------+------+---------------+--------+---------+-------+------+-------------+
| id | select_type | table   | type | possible_keys | key    | key_len | ref   | rows | Extra       |
+----+-------------+---------+------+---------------+--------+---------+-------+------+-------------+
|  1 | SIMPLE      | ejemplo | ref  | indice        | indice | 5       | const |    1 | Using where |
+----+-------------+---------+------+---------------+--------+---------+-------+------+-------------+
1 row in set (0.01 sec)



Que curioso ahora fijate en la parte donde dice rows -> 1 (recorrio 1 sola fila para dar exactamente con mi registro en vez de recorrer todos los registros como haria sino tengo un indice definido).




seba123neo

si es verdad al poner indices en la base, aumenta considerablemente la velocidad de busqueda en los selects, yo diria que lo pongas, total mal no te va a venir,y mejor ponerlo ahora que depues cuando se presente algun problema. ¿año no hay?
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

Skeletron

Claro.. lo entendí muy bien Tifa..
Como siempre, me falta "detallarme" mas..
Las entradas son 18.500 y no aumentarán mucho.. es mas, podrian aumentarse unas 5 o 6 entradas por MES.. pero al cabo de 1 o 2 años, no creo que aumente mucho... (a no ser que luego de un tiempo haga éste software 2.0)

Te comento como es la aplicacion así te das cuenta que me conviene para hacer Indice:
En la aplicacion hay un CALENDARIO, que al hacerle click en un dia, llama a la sentencia SELECT texto FROM Efemerdies where mes='messeleccionado' and dia='diaseleccionado'

Por dia hay unas 50 efemerides, y esas efemerides se agregaran en un la LISTA de items de vb.net
lsita.item.add(SQLReader(0))
Se entiende??

Esa base de datos esta en la PC del usuario.. así que no hya MULTIPLES lecturas simultaneas a la base de datos..

Pero igual, la idea es que mas o menos en 6 meses haga a ese Software de tipo 2.0, para que la gente pueda agregar "Efemerides" importantes.. para que yo las analice y las "acepte" y se areguen a la base de datos (que se actualiza automaticamente.. pero eso ya lo tengo FRITO)

Entonces, ahroa sabiendo que mi SELECT tiene que buscar entre todas las entradas, y seleccionar las entradas de X mes (que dará como resultado unas 1.200 entradas..) y entre esas 1.200 tiene que seleccionar las de dia X, que serán aproximadamente 50..

Tendré que poner INDICE a MES? a DIA? o a Ambos?
Porque leí que exederse de Indices, tambien es malo.. seguramente ustedes saben que convendria..

Novlucker

Lo que plantea ^TiFa^ esta excelente (como siempre  ;)), no obstante, yo decía que no lo veía necesario porque suponía que era justamente para tu programa de efemerides, las cuales son limitadas y se consultan un número acotado de veces (en un intervalo dado)  :P, además de que en tu caso necesitas recuperar las 50 efemerides y no un solo registro, personalmente no lo pondría, pero creo que le haría caso a ^TiFa^ de sugerir hacerlo de cualquier manera, tiene más experiencia que yo con BBDD

Saludos
Contribuye con la limpieza del foro, reporta los "casos perdidos" a un MOD XD

"Hay dos cosas infinitas: el Universo y la estupidez  humana. Y de la primera no estoy muy seguro."
Albert Einstein