简体   繁体   English

在此查询上使用 RIGHT JOIN 时 JOIN 非常慢

[英]JOIN very slow when using RIGHT JOIN on this query

I'm having a problem with this query that takes several seconds to complete.这个查询有问题,需要几秒钟才能完成。 I already tried many optimizations but I'm shooting blanks at this point.我已经尝试了很多优化,但此时我正在拍摄空白。

The tables are the following (and are not absolutely normalized fully especially the tracks table)表格如下(并没有完全完全标准化,尤其是曲目表)

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

and the query I'm trying to execute with a normal speed is the following我试图以正常速度执行的查询如下

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');

Where if you remove the RIGHT JOIN and change it to JOIN it is fast如果你删除 RIGHT JOIN 并将其更改为 JOIN 它很快

The EXPLAIN gives me this result, it seems there is a small problem in the efave selection but I have no idea how to get that out EXPLAIN 给了我这个结果,似乎在 efave 选择中有一个小问题,但我不知道如何解决这个问题

+----+-------------+--------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------+
| 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                  | 3210 |   100.00 |                          |
+----+-------------+--------+--------+---------------+---------+---------+-----------------------+------+----------+--------------------------+

Your explain looks clean, the only thing that stands out to me is the fact that the esong table is using a collate of utf8_bin , and the tracks table doesn't have a collation specified, which means it is probably using another collation type.你的解释看起来很干净,唯一让我印象深刻的是esong表使用的是 utf8_bin 的排序规则,而 tracks 表没有指定排序规则,这意味着它可能正在使用另一种排序规则类型。 Try aligning your collations and see how the join performs.尝试对齐排序规则并查看连接的执行情况。

Have you checked your Execution Plan?你检查过你的执行计划了吗? If not, run your query to include it.如果没有,请运行您的查询以包含它。 Your Right Join may be doing an Index Scan instead of an Index Seek.您的 Right Join 可能正在进行索引扫描而不是索引查找。 Or you may be lacking indexes.或者您可能缺少索引。 Either way, you need to look at your Execution Plan so you can optimize your query better.无论哪种方式,您都需要查看执行计划,以便更好地优化查询。 No one will really be able to tell you how to make it faster using a Right Join (or a Join for that matter) until you know what the real problem is.在您知道真正的问题是什么之前,没有人能够真正告诉您如何使用 Right Join(或与此相关的 Join)使其更快。 Here are some links.. For MySQL: http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html For SqlServer: http://www.sql-server-performance.com/2006/query-execution-plan-analysis/这里有一些链接.. 对于 MySQL: http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html对于 SqlServer: http://www.sql-server-performance.com /2006/查询执行计划分析/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM