2012-04-05 53 views
6

我遇到此查詢需要幾秒鐘才能完成的問題。我已經嘗試了很多優化,但是我現在在拍攝空白。在此查詢中使用RIGHT JOIN時JOIN速度很慢

表是以下(而不是絕對的完全正常化特別是軌道表)

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 

,我試圖用正常的速度執行查詢是以下

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

如果刪除RIGHT JOIN並將其更改爲JOIN,則速度很快

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

'tracks'表的'COLLATE'值是什麼? – 2012-04-05 00:30:06

回答

5

你的解釋看起來乾淨,脫穎而出,以我的唯一的事情是事實ESONG表使用的一個整理utf8_bin,和軌道表沒有指定的歸類,這意味着它可能使用另一個歸類類型。嘗試對齊排序規則並查看聯接的執行方式。

+0

這確實是個問題,軌道表上的排序規則是utf8_general_ci,而其他三個規則是utf8_bin。絕對的輝煌。 – Wessie 2012-04-05 00:52:44

+0

啊,很高興它的工作。我假設你添加了utf8_bin collat​​e到軌道表? – 2012-04-05 03:56:45

+2

我最初添加了utf8_bin到軌道,但是這使得全文索引區分大小寫。所以我改爲全部改爲utf8_general_ci。 – Wessie 2012-04-05 08:41:41

0

您是否檢查過執行計劃?如果沒有,請運行您的查詢以包含它。您的正確加入可能會進行索引掃描而不是索引查找。或者你可能缺乏索引。無論哪種方式,您都需要查看執行計劃,以便更好地優化查詢。沒有人真的能夠告訴你如何使用正確的加入(或加入這個問題)來加快速度,直到你知道真正的問題是什麼。這裏有一些鏈接.. 對於MySQL:http://dev.mysql.com/doc/refman/5.5/en/execution-plan-information.html 使用Sql Server:http://www.sql-server-performance.com/2006/query-execution-plan-analysis/

+1

問題中有執行計劃 - 最後一個解釋輸出。 – piotrm 2012-04-05 00:42:59

+0

對不起,我沒有意識到這是執行計劃的結果。我甚至沒有檢查 - 我認爲這是你的查詢本身的結果。讓我檢查一下。 – 2012-04-05 00:52:51