簡體   English   中英

在此查詢上使用 RIGHT JOIN 時 JOIN 非常慢

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

這個查詢有問題,需要幾秒鍾才能完成。 我已經嘗試了很多優化,但此時我正在拍攝空白。

表格如下(並沒有完全完全標准化,尤其是曲目表)

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

你的解釋看起來很干凈,唯一讓我印象深刻的是esong表使用的是 utf8_bin 的排序規則,而 tracks 表沒有指定排序規則,這意味着它可能正在使用另一種排序規則類型。 嘗試對齊排序規則並查看連接的執行情況。

你檢查過你的執行計划了嗎? 如果沒有,請運行您的查詢以包含它。 您的 Right Join 可能正在進行索引掃描而不是索引查找。 或者您可能缺少索引。 無論哪種方式,您都需要查看執行計划,以便更好地優化查詢。 在您知道真正的問題是什么之前,沒有人能夠真正告訴您如何使用 Right Join(或與此相關的 Join)使其更快。 這里有一些鏈接.. 對於 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