Problema de rendimiento en BBDD

Me va demasiado lento hacer esto:

Contenido.all(:conditions => “tema = 11”, :order => “created_at”, :limit
=> 2)

La tabla “contenidos” tiene 200.000 registros, de los cuales unos 20.000
tienen tema=11; pero tengo definido un índice sobre los campos (tema +
created_at), de forma que la BBDD entiendo que debería acceder
directamente a los registros en cuestión…

Sin embargo, no va como debería, y un “explain SELECT * FROM contenidos
WHERE tema = 11 ORDER BY created_at LIMIT 2;” revela que, aun pasando
por el índice correcto, está recorriendo 13958 registros!! ¿Alguien sabe
cuál puede ser el problema?

s2

Sería de gran utilidad que pegaras ese EXPLAIN (ejecutado con \G) y un
show index de esa tabla.

2008/12/1 Fernando C. [email protected]:

Fernando B. wrote:

Sería de gran utilidad que pegaras ese EXPLAIN (ejecutado con \G) y un
show index de esa tabla.

2008/12/1 Fernando C. [email protected]:

Estoy alucinando… ahora el mismo explain dice que pasa por 491
registros, empleando el mismo índice!!

Respecto al explain, dice esto:
Possible keys: index_contenidos_on_tema_and_created_at,
index_contenidos_on_tema_and_ultima_respuesta_id,
index_contenidos_on_tema_and_veces_leido,
index_contenidos_on_tema_and_respuestas_count

Key: index_contenidos_on_tema_and_created_at

Key_len: 5

Ref: const

Rows: 491 (hoy)

Extra: Using where

Y la tabla:

CREATE TABLE contenidos (
id int(11) NOT NULL auto_increment,
parent_id int(11) default NULL,
inicial_id int(11) default NULL,
usuario_id int(11) NOT NULL,
subtipo_id int(11) NOT NULL,
publicado tinyint(1) default ‘1’,
tema int(11) default ‘0’,
titulo varchar(255) NOT NULL,
texto_completo text,
keywords varchar(255) default NULL,
descripcion varchar(400) default NULL,
permalink varchar(255) default NULL,
contenido_link varchar(255) default NULL,
usr_nick varchar(255) default NULL,
usr_nick_limpio varchar(255) default NULL,
veces_leido int(11) default ‘0’,
votos_count int(11) default ‘0’,
images_count int(11) default ‘0’,
respuestas_count int(11) default ‘0’,
ultima_respuesta_id int(11) default NULL,
contador int(11) default ‘0’,
producto_id int(11) default NULL,
lo_mejor varchar(255) default NULL,
lo_peor varchar(255) default NULL,
area1 int(11) default NULL,
area2 int(11) default NULL,
area3 int(11) default NULL,
puntuacion int(11) default NULL,
cliente varchar(255) default NULL,
fecha_cliente datetime default NULL,
cotizacion decimal(10,2) default NULL,
copyright varchar(255) default NULL,
fecha_titulares datetime default NULL,
created_ip varchar(255) default NULL,
updated_ip varchar(255) default NULL,
updated_usuario varchar(255) default NULL,
created_at datetime default NULL,
updated_at datetime default NULL,
leido_dia int(11) default ‘0’,
leido_semana int(11) default ‘0’,
PRIMARY KEY (id),
KEY ultima_respuesta_id (ultima_respuesta_id),
KEY index_contenidos_on_inicial_id_and_publicado_and_created_at
(inicial_id,publicado,created_at),
KEY index_contenidos_on_usuario_id_and_inicial_id
(usuario_id,inicial_id),
KEY index_contenidos_on_tema_and_created_at (tema,created_at),
KEY index_contenidos_on_subtipo_id_and_created_at
(subtipo_id,created_at),
KEY index_contenidos_on_created_at (created_at),
KEY index_contenidos_on_usuario_subtipo_publicado_created_at
(usuario_id,subtipo_id,publicado,created_at),
KEY index_contenidos_on_usuario_id_and_tema_and_created_at
(usuario_id,tema,created_at),
KEY index_contenidos_on_tema_and_ultima_respuesta_id
(tema,ultima_respuesta_id),
KEY index_contenidos_on_tema_and_veces_leido (tema,veces_leido),
KEY index_contenidos_on_tema_and_respuestas_count
(tema,respuestas_count),
KEY index_contenidos_on_producto_id_and_publicado_and_created_at
(producto_id,publicado,created_at),
KEY index_contenidos_on_parent_id_and_publicado_and_created_at
(parent_id,publicado,created_at),
KEY index_contenidos_on_fecha_titulares (fecha_titulares),
KEY index_contenidos_on_subtipo_id_and_publicado_and_created_at
(subtipo_id,publicado,created_at),
KEY index_contenidos_on_usuario_publicado_created_at
(usuario_id,publicado,created_at),
KEY index_contenidos_on_usuario_id_and_created_at
(usuario_id,created_at),
CONSTRAINT contenidos_ibfk_1 FOREIGN KEY (parent_id) REFERENCES
contenidos (id),
CONSTRAINT contenidos_ibfk_2 FOREIGN KEY (inicial_id) REFERENCES
contenidos (id),
CONSTRAINT contenidos_ibfk_3 FOREIGN KEY (usuario_id) REFERENCES
usuarios (id),
CONSTRAINT contenidos_ibfk_4 FOREIGN KEY (subtipo_id) REFERENCES
subtipos (id),
CONSTRAINT contenidos_ibfk_5 FOREIGN KEY (ultima_respuesta_id)
REFERENCES contenidos (id),
CONSTRAINT contenidos_ibfk_6 FOREIGN KEY (producto_id) REFERENCES
productos (id)
) ENGINE=InnoDB AUTO_INCREMENT=226129 DEFAULT CHARSET=utf8

s2

Emili Parreño wrote:

Has probado a poner una logintud de indice más larga, 10 por ejemplo??,
de
todas maneras reducir de 20.000 a 500 no esta mal, deberia ejecutarte la
query bastante rapido.

El 2 de diciembre de 2008 10:22, Fernando C. <
[email protected]lid> escribió:

¿La longitud de la clave se puede modificar? Creía que Mysql le ponía la
que necesita para abarcar estos campos (en este caso, un entero y una
fecha).

De todos modos, con 491 filas claro que va bien, el tema es que ayer me
daba 13958 filas…

Has probado a poner una logintud de indice más larga, 10 por ejemplo??,
de
todas maneras reducir de 20.000 a 500 no esta mal, deberia ejecutarte la
query bastante rapido.

El 2 de diciembre de 2008 10:22, Fernando C. <
[email protected]> escribió:

Emili Parreño wrote:

Puedes especificar la longitud del indice por ejemplo así

def self.up
execute “CREATE INDEX users_full_name ON users (name(10),
surname(10))”
end

El 2 de diciembre de 2008 14:03, Fernando C. <
[email protected]> escribió:

En los campos de texto sí, pero ¿en los int y datetime? ¿No los coge
enteros?

s2 y gracias!!

Puedes especificar la longitud del indice por ejemplo así

def self.up
execute “CREATE INDEX users_full_name ON users (name(10),
surname(10))”
end

El 2 de diciembre de 2008 14:03, Fernando C. <
[email protected]> escribió:

El indice lo crea por defecto con una longitud igual al tamaño máximo
del
campo en cuestión, si es un varchar le pone una longitud de 255
carácteres,
a no ser que tú lo hayas limitado. En tu caso tienes un datetime (12
bytes)
y un entero (4 bytes), es este caso deberia crear un indice de longitud
16,
cosa que por lo que dices no hace, fuerzalo y ponle longitud 16 a ver
que
pasa.

El 2 de diciembre de 2008 17:13, Fernando C. <
[email protected]> escribió:

Yo creo que está bien… y el explain no se está quejando… no?

Hay una movida con los índices y los order by DESC/ASC que por defecto
se crean con un órden y si los invocas con el otro es como si el
índice no existiera.

Te suena que ayer lanzases la query con un order by diferente al de hoy?

f.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs