Query-reviewer y optimización con índ ices en tablas

¿Habéis probado el plugin query-reviewer? [1]

Lo he estado usando para encontrar cuellos de botella en mis
aplicaciones, principalmente falta de índices en algunas tablas, y me
ha venido muy bien… pero hay algún warning que no he conseguido
saber cómo solucionar…

En concreto, me avisa de “long key length” en el método show de mi
controlador de plantas en floragavarres.net, donde localizo las
plantas a través de su slug (con sluggable_finder), por ejemplo:

http://floragavarres.net/carthamus-lanatus-l-subsp-lanatus

Puse un índice para la columna “slug” en la tabla “plants” para poder
buscar por ese campo rápidamente… ahora las encuentra rápido pero
dice que la clave es demasiado larga…

Table plants: Long key length (768)
The key used for the index was rather long, potentially affecting
indices in memory

¿Se os ocurre por dónde mirar para solucionar este warning?

[1] Google Code Archive - Long-term storage for Google Code Project Hosting.


Jaime I.
http://jaimeiniesta.com - http://pagerankalert.com -
http://floragavarres.net

El día 5 de agosto de 2008 15:07, Jaime I.
[email protected]
escribió:>

http://floragavarres.net/carthamus-lanatus-l-subsp-lanatus

Puse un índice para la columna “slug” en la tabla “plants” para poder
buscar por ese campo rápidamente… ahora las encuentra rápido pero
dice que la clave es demasiado larga…

Table plants: Long key length (768)
The key used for the index was rather long, potentially affecting
indices in memory

¿Cuál es la base de datos?
¿Podés poner la definición de la tabla (tal como quedó en la base)?
¿Los valores en el campo se repiten mucho?

Silvio

Completamente de acuerdo en que ese plugin es una gran ayuda para
encontrar slow querys y demás.

El warning que te reporta se debe a que el índice es sobre un string y
si no le dices nada a Mysql el índice lo aplica sobre la longitud del
campo varchar.

Según tengo entendido, se ve que cuando hay muchísimas filas un índice
tan grande consume mucha memoria, y es recomendable hacer un índice de
parte de la longitud del campo, intentando llegar a un compromiso
entre eficiencia del índice y uso de memoria:

  • cuanto más pequeña sea la longitud del índice menos memoria consumirá
  • sin embargo cuanto más pequeño menos eficiente es, porque el índice
    se aplica a una subcadena y no sobre la cadena entera.

Es muy sencillo:

si tienes un campo string con con valores:

juanitowadus
juanitomenglanito
pepitojuanito
pepitosotanito
pepitomenglanito
pepitopedrito

y tu índice es de 6 caracteres, cuando busques “pepitomenglanito” el
índice te devolverá las 4 entradas que empiecen por “pepito” porque
hará matching rápidamente y el resto de la búsqueda terminará sin
índice.

Lo suyo es encontrar una longitud de caractéres óptima que ayude a
discriminar rápidamente. Quizá con 2 o 3 sea suficiente y ya
discrimina entre las tres primeras letras.

Eso sí, no sé si el add_index de rails de las migraciones permite
indicar longitud del índice :slight_smile: Supongo que sí.

2008/8/5 Jaime I. [email protected]:

En la documentación sobre migraciones [1] no lo especifica, y en la del
método add_index tampoco. En MySQL se hace así:
ALTER TABLE plantas ADD INDEX ( slug(4) )

Otra cosa a tener en cuenta es si el índice debe ser único o no, en el
caso
de slugs o permalinks sí deberá serlo. En tablas InnoDB un índice único
es
prácticamente lo mismo que una clave primaria, así que las búsquedas son
muy
rápidas. Se puede añadir un índice único en una migración así:

add_index(:plantas,:slug, :unique => true)
Tienes otra opción que yo he aplicado a veces, utilizar el slug solo
para
decorar la url, pero buscando por id, por ejemplo con urls del tipo

http://floragavarres.net/34/centaurea-cyanus-l

o

http://floragavarres.net/centaurea-cyanus-l/34

y mapear una ruta p.e.

map.ver_panta “/:id/:slug”, :controller => “plantas”, :action => “show”

así la url queda bonita pero las búsquedas son por id ya que puedes
hacer un
Planta.find(params[:id])

e[1] ActiveRecord::Migration

El 5 de agosto de 2008 20:25, Fernando B.[email protected]escribió:

El día 6 de agosto de 2008 0:19, Emili Parreño [email protected]
escribió:> En la documentación sobre migraciones [1] no lo especifica, y en la del

método add_index tampoco. En MySQL se hace así:
ALTER TABLE plantas ADD INDEX ( slug(4) )

Es una pena que no lo hayan incluido en la sintaxis de las migraciones
todavía.

Otra cosa a tener en cuenta es si el índice debe ser único o no, en el caso
de slugs o permalinks sí deberá serlo. En tablas InnoDB un índice único es
prácticamente lo mismo que una clave primaria, así que las búsquedas son muy
rápidas. Se puede añadir un índice único en una migración así:
add_index(:plantas,:slug, :unique => true)

Sip.

Tienes otra opción que yo he aplicado a veces, utilizar el slug solo para
decorar la url, pero buscando por id, por ejemplo con urls del tipo
http://floragavarres.net/34/centaurea-cyanus-l
o
http://floragavarres.net/centaurea-cyanus-l/34
y mapear una ruta p.e.
map.ver_panta “/:id/:slug”, :controller => “plantas”, :action => “show”
así la url queda bonita pero las búsquedas son por id ya que puedes hacer un
Planta.find(params[:id])

Buena idea también, aunque es una pena que no queden tan bonitas las
URLs… Mejor las dejo como las tengo.

El día 5 de agosto de 2008 20:25, Fernando B. [email protected]
escribió:> Completamente de acuerdo en que ese plugin es una gran ayuda para

encontrar slow querys y demás.

Sip, está guay. Pero como con todos los plugins, ¡cuidado! Ayer me
daban errores en la aplicación que no comprendía, concretamente al
borrar fotos, me dice que nosequé de nil.table… y si quito el
plugin, no falla. Así que mola usarlo, viene muy bien, pero si la app
os hace cosas raras, desconfiad!

Lo suyo es encontrar una longitud de caractéres óptima que ayude a
discriminar rápidamente. Quizá con 2 o 3 sea suficiente y ya
discrimina entre las tres primeras letras.

Genial, he probado con una longitud de 25 caracteres para el índice
del campo slug y query-reviewer ya dice que SQL OK.

Lo que no entiendo es que el index diga que tiene 768 caracteres
cuando se trata de un varchar(255).

Eso sí, no sé si el add_index de rails de las migraciones permite
indicar longitud del índice :slight_smile: Supongo que sí.

Pues me parece que no… hay un parche propuesto [1] pero he probado
con :length y no hace caso.

[1] http://dev.rubyonrails.org/ticket/9254

Gracias!

Hombre,

una cosa no quita a la otra: en producción está claro que es mejor
tenerlo activado para estar continuamente atendiendo a posibles
problemas, pero en desarrollo el query reviewer te ahorra el tener que
ir a buscar el log y luego pensar a qué petición correspondía tal
query.

Vamos, que es muy cómodo. Pero claro, en producción no se puede
utilizar bajo ningún concepto.

2008/8/7 Francesc E. [email protected]:

El día 6 de agosto de 2008 9:45, Jaime I.
[email protected]
escribió:> El día 6 de agosto de 2008 0:19, Emili Parreño [email protected] escribió:

En la documentación sobre migraciones [1] no lo especifica, y en la del
método add_index tampoco. En MySQL se hace así:
ALTER TABLE plantas ADD INDEX ( slug(4) )

Es una pena que no lo hayan incluido en la sintaxis de las migraciones todavía.

El parche a mí me ha funcionado perfectamente… si bien lo que he
hecho es ‘abrir’ el código y modificarlo directamente en mi
aplicaciónasí no toco el código original de la gema:

Otra cosa a tener en cuenta es si el índice debe ser único o no, en el caso
de slugs o permalinks sí deberá serlo. En tablas InnoDB un índice único es
prácticamente lo mismo que una clave primaria, así que las búsquedas son muy
rápidas. Se puede añadir un índice único en una migración así:
add_index(:plantas,:slug, :unique => true)

Sip.

Cuidado si se está limitando el tamaño de este índice pues si le has
puesto un tamaño 10, por ejemplo, marcará que tendrá que ser único
usando sólo los 10 primeros caracteres.

Saludos
f.

Para mirar las slow queries no creis que es mejor activar las slow
queries de MySQL?