2014-01-30 35 views
1

下面是我的EXPLAIN查詢和輸出。我非常喜歡初學者(請原諒我的SQL語法...除非這是我的問題!) - 任何人都可以在這裏解釋表的順序嗎?我玩過訂單(在查詢本身中),但TABLE 藝術家始終在EXPLAIN輸出中位居首位?我收集有關表訪問時的順序 - 如果是這樣,爲什麼藝術家第一?試圖理解mySQL中查詢的EXPLAIN結果

EXPLAIN 
SELECT album_name, artist_name, genre_name 
FROM albums 
JOIN genres USING (genre_pk) 
JOIN artists USING (artist_pk) 
ORDER BY album_name; 


| id | select_type | table | type | possible_keys  | key  | key_len | ref      | rows | Extra       | 
+----+-------------+---------+--------+--------------------+-----------+---------+-------------------------+------+---------------------------------+ 
| 1 | SIMPLE  | artists | ALL | PRIMARY   | NULL  | NULL | NULL     | 5 | Using temporary; Using filesort | 
| 1 | SIMPLE  | albums | ref | genre_pk,artist_pk | artist_pk | 2  | music.artists.artist_pk | 1 | NULL       | 
| 1 | SIMPLE  | genres | eq_ref | PRIMARY   | PRIMARY | 1  | music.albums.genre_pk | 1 | NULL       | 

SHOW CREATE TABLE信息:

CREATE TABLE `artists` (
    `artist_pk` smallint(4) unsigned NOT NULL AUTO_INCREMENT, 
    `artist_name` varchar(57) NOT NULL, 
    `artist_origin` enum('UK','US','OTHER') DEFAULT NULL, 
    PRIMARY KEY (`artist_pk`) 
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1; 

CREATE TABLE `genres` (
    `genre_pk` tinyint(2) unsigned NOT NULL AUTO_INCREMENT, 
    `genre_name` varchar(30) NOT NULL, 
    PRIMARY KEY (`genre_pk`), 
    UNIQUE KEY `genre_name` (`genre_name`) 
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=latin1; 

CREATE TABLE `albums` (
    `album_pk` smallint(4) unsigned NOT NULL AUTO_INCREMENT, 
    `genre_pk` tinyint(2) unsigned NOT NULL, 
    `artist_pk` smallint(4) unsigned NOT NULL, 
    `album_name` varchar(57) NOT NULL, 
    `album_year` year(4) DEFAULT NULL, 
    `album_track_qty` tinyint(2) unsigned NOT NULL, 
    `album_disc_num` char(6) NOT NULL DEFAULT '1 of 1', 
    PRIMARY KEY (`album_pk`), 
    KEY `genre_pk` (`genre_pk`), 
    KEY `artist_pk` (`artist_pk`), 
    FULLTEXT KEY `album_name` (`album_name`), 
    CONSTRAINT `albums_ibfk_1` FOREIGN KEY (`genre_pk`) REFERENCES `genres` (`genre_pk`), 
    CONSTRAINT `albums_ibfk_2` FOREIGN KEY (`artist_pk`) REFERENCES `artists` (`artist_pk`) 
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1; 
+0

僅供參考,人們一般習慣於閱讀解釋計劃標準輸出格式,即在查詢結尾使用';'而不是'\ G'。你可以編輯你的文章以包含EXPLAIN PLAN輸出嗎? – dg99

+0

[MySQL解釋查詢理解]的可能的重複(http://stackoverflow.com/questions/7999833/mysql-explain-query-understanding) – Imran

+0

確定的事情@ dg99,我這樣做,因爲我認爲它可能更容易讀。我們生活和學習。 – simien

回答

0

這裏是你的小提琴:http://sqlfiddle.com/#!2/a6224/2/0

正如@Daniel已經說過,MySQL的考慮不僅是指數,而且在每個表中的行數。在我的小提琴和數據庫中,行數都很低 - 所以很難責怪MySQL。

注意,即使STRAIGHT_JOIN將使得順序加入似乎是順理成章的你,也不會然而令的執行計劃漂亮(我的意思是Using temporary; Using filesort紅旗)

+0

您能否詳細說明您使用小提琴的方式?歡呼你所有的幫助,每個人。 – simien

+0

sqlfiddle只是一個工具,您可以共享您的數據庫模式和查詢 - 並將鏈接附加到您的Stackoverflow問題。對於那些閱讀你的問題的人來說這很方便 - 他們不需要在他們自己的MySQL安裝上創建測試環境。在sqlfiddle上,您可以針對您的模式運行SELECT語句,然後單擊「查看執行計劃」鏈接以查看EXPLAIN輸出 - 或者您可以直接運行EXPLAIN SELECT查詢。 –

2

加入你的表的順序是根據SQL優化器。優化程序在內部修改您的查詢以快速高效地交付結果(read this page for more details)。要避免內部連接優化,您可以使用SELECT STRAIGHT_JOIN

在您的特例中,順序取決於每個表中的行數和索引的可用性。看一下these slides從第25頁開始就有一個小例子。