2012-04-05 13 views
6

Tengo un problema con esta consulta que tarda varios segundos en completarse. Ya probé muchas optimizaciones pero estoy disparando espacios en blanco en este punto.ÚNASE muy lento al usar DERECHA UNIRSE en esta consulta

Las tablas son las siguientes (y no se normalizan absolutamente totalmente en especial la tabla pistas)

CREATE TABLE `tracks` (
`id` int(14) unsigned NOT NULL AUTO_INCREMENT, 
`artist` varchar(200) NOT NULL, 
`track` varchar(200) NOT NULL, 
`album` varchar(200) NOT NULL, 
`path` text NOT NULL, 
`tags` text NOT NULL, 
`priority` int(10) NOT NULL DEFAULT '0', 
`lastplayed` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
`lastrequested` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
`usable` int(1) NOT NULL DEFAULT '0', 
`accepter` varchar(200) NOT NULL DEFAULT '', 
`lasteditor` varchar(200) NOT NULL DEFAULT '', 
`hash` varchar(40) DEFAULT NULL, 
PRIMARY KEY (`id`), 
UNIQUE KEY `hash` (`hash`), 
FULLTEXT KEY `searchindex` (`tags`,`artist`,`track`,`album`), 
FULLTEXT KEY `artist` (`artist`,`track`,`album`,`tags`) 
) ENGINE=MyISAM AUTO_INCREMENT=3336 DEFAULT CHARSET=utf8 

CREATE TABLE `esong` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
`hash` varchar(40) COLLATE utf8_bin NOT NULL, 
`len` int(10) unsigned NOT NULL, 
`meta` text COLLATE utf8_bin NOT NULL, 
PRIMARY KEY (`id`), 
UNIQUE KEY `hash` (`hash`) 
) ENGINE=InnoDB AUTO_INCREMENT=16032 DEFAULT CHARSET=utf8 COLLATE=utf8_bin 

CREATE TABLE `efave` (
`id` int(10) unsigned NOT NULL DEFAULT '0', 
`inick` int(10) unsigned NOT NULL, 
`isong` int(10) unsigned NOT NULL, 
UNIQUE KEY `inick` (`inick`,`isong`), 
KEY `isong` (`isong`), 
CONSTRAINT `inick` FOREIGN KEY (`inick`) REFERENCES `enick` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, 
CONSTRAINT `isong` FOREIGN KEY (`isong`) REFERENCES `esong` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

CREATE TABLE `enick` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT 
`nick` varchar(30) COLLATE utf8_bin NOT NULL, 
`dta` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
`dtb` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
PRIMARY KEY (`id`), 
KEY `nick` (`nick`) 
) ENGINE=InnoDB AUTO_INCREMENT=488 DEFAULT CHARSET=utf8 COLLATE=utf8_bin 

y la consulta que estoy tratando de ejecutar con una velocidad normal es el siguiente

SELECT esong.meta, tracks.id FROM tracks RIGHT JOIN esong ON tracks.hash = esong.hash JOIN efave ON efave.isong = esong.id JOIN enick ON efave.inick = enick.id WHERE enick.nick = lower('nickname'); 

Donde si elimina el DERECHO ÚNASE y cámbielo a UNIRSE es rápido

El EXPLAIN me da este resultado, parece que hay un pequeño problema en el efave selección pero no tengo ni idea de cómo sacarlo

+----+-------------+--------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref     | rows | filtered | Extra     | 
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------+ 
| 1 | SIMPLE  | enick | ref | PRIMARY,nick | nick | 92  | const     | 1 | 100.00 | Using where; Using index | 
| 1 | SIMPLE  | efave | ref | inick,isong | inick | 4  | radiosite.enick.id | 12 | 100.00 | Using index    | 
| 1 | SIMPLE  | esong | eq_ref | PRIMARY  | PRIMARY | 4  | radiosite.efave.isong | 1 | 100.00 |       | 
| 1 | SIMPLE  | tracks | ALL | hash   | NULL | NULL | NULL     || 100.00 |       | 
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------+ 
+1

¿Cuál es el valor 'COLLATE' de la tabla' tracks'? –

Respuesta

5

Sus explicar aspecto limpio, lo único que se destaca para mí es el hecho de que la mesa Esong utiliza una intercalación de utf8_bin, y la tabla de pistas no tiene una intercalación especificada, lo que significa que probablemente esté utilizando otro tipo de intercalación. Intenta alinear tus intercalaciones y ver cómo se realiza la unión.

+0

Este fue de hecho el problema, la intercalación en la tabla de pistas fue utf8_general_ci, mientras que las otras tres fueron utf8_bin. Absolutamente brillante. – Wessie

+0

Ahhh me alegro de que funcionó. Supongo que agregaste utf8_bin a la tabla de pistas? –

+2

Inicialmente agregué utf8_bin a las pistas, pero esto hacía que el índice de texto completo fuera sensible a mayúsculas y minúsculas. Así que los cambié a todos por utf8_general_ci en su lugar. – Wessie

0

¿Has comprobado tu plan de ejecución? Si no, ejecuta tu consulta para incluirlo. Su combinación correcta puede estar haciendo una exploración de índice en lugar de una búsqueda de índice. O puede que le falten índices. De cualquier manera, debe consultar su plan de ejecución para poder optimizar mejor su consulta. Nadie podrá decirle cómo hacerlo más rápido utilizando un Ensamble correcto (o unirme para ese asunto) hasta que sepa cuál es el problema real. Estos son algunos enlaces .. Para MySQL: http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html Para SqlServer: http://www.sql-server-performance.com/2006/query-execution-plan-analysis/

+1

Hay un plan de ejecución en la pregunta: el último resultado de explicación. – piotrm

+0

Lo siento, no me di cuenta de que ese fue el resultado del plan de ejecución. Ni siquiera comprobé, pensé que eran los resultados de tu consulta. Dejame revisar. –