2010-10-04 68 views
2

與未來將如何相比,2個表仍然非常小。 已經在對一些常規查詢進行測試時,會出現性能問題。(MySQL)最大數量按組內部連接,性能問題

有人可以啓發我一個更好的表結構或查詢嗎?

====

表1:TV_SHOW(目前117行)

表2:tv_episodes(目前43000行)。

TV_SHOW包含ID,我們在tv_episodes呼籲T_ID

tv_episodes包含此t_id和字段episodes_num

每集具有插曲號季號episodes_num被總集數不分季節。

例如:所有的季節有10分集:第2季第1集= episodes_num:

現在的查詢: 我希望每個電視節目的最新episodes_num。

SELECT tv.*,ep.* FROM tv_show tv 
INNER JOIN tv_episodes ep ON (tv.id = ep.t_id) 
LEFT OUTER JOIN tv_episodes ep2 
ON (tv.id = ep2.t_id AND ep.episode_num < ep2.episode_num) 
WHERE ep2.t_id is NULL 

這工作,但給服務器一個非常艱難的時間(查詢超過10秒!)

請幫助。

編輯:的MySQL版本:* 5.1.47

更新:感謝人的解決方案,這是一個這是最快的。

SELECT tv_episodes.* ,tv_show.* 

    FROM tv_episodes 
    INNER JOIN 
    (
     SELECT t_id, MAX(episode_num) AS episode_num 

     FROM tv_episodes 
     GROUP BY t_id 
    ) max_eps 
    ON tv_episodes.t_id = max_eps.t_id AND tv_episodes.episode_num = max_eps.episode_num 
    INNER JOIN 
tv_show ON tv_show.id=tv_episodes.t_id 



CREATE TABLE `tv_show` (
`id` int(255) NOT NULL AUTO_INCREMENT, 
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
`specification` varchar(50) NOT NULL, 
`year` int(4) NOT NULL, 
`status` varchar(100) NOT NULL, 
PRIMARY KEY (`id`), 
KEY `name` (`name`), 
KEY `specification` (`specification`), 
KEY `year` (`year`), 
KEY `status` (`status`) 
) ENGINE=MyISAM AUTO_INCREMENT=118 DEFAULT CHARSET=latin1 





CREATE TABLE `tv_episodes` (
`id` int(255) NOT NULL AUTO_INCREMENT COMMENT 'e_id', 
`t_id` int(200) NOT NULL, 
`season` int(2) NOT NULL, 
`episode` int(4) NOT NULL, 
`episode_num` int(10) NOT NULL, 
`airing` date NOT NULL, 
`online` enum('1','2') NOT NULL COMMENT '1=yes 2=no', 
`added` int(15) NOT NULL, 
`title` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL, 
PRIMARY KEY (`id`), 
KEY `t_id` (`t_id`), 
KEY `season` (`season`), 
KEY `episode` (`episode`), 
KEY `season_num` (`episode_num`), 
KEY `airing` (`airing`), 
KEY `added` (`added`) 
) ENGINE=MyISAM AUTO_INCREMENT=43420 DEFAULT CHARSET=latin1 

回答

1

更新:根據您的最新評論和我自己的調整,我編輯了我的答案。

這將返回tv_episode記錄每個TV_ID具有最大episodes_num

SELECT tv_episodes.* 
FROM tv_episodes 
INNER JOIN 
(
    SELECT t_id, MAX(episodes_num) AS episodes_num 
    FROM tv_episodes 
    GROUP BY t_id 
) max_eps 
ON tv_episodes.t_id = max_eps.t_id AND tv_episodes.episodes_num = max_eps.episodes_num; 
+0

這只是一個開始:使其更清楚。在連接中會添加更多表,稱爲tv_show_info,tv_plots,tv_genres。我想要一個帶有電視節目名稱+信息的最新電視節目劇集列表。這就是目標。您的最新查詢,幾乎與我的執行時間相同..感謝您的所有輸入! – 2010-10-04 17:14:22

+0

非常感謝!這是我正在尋找的最後一個查詢...查詢時間很好,它會得到結果。 – 2010-10-04 21:18:26

0

如果您使用的高MSSQL 2005(未指定的數據庫系統和版本),你可以使用 「應用」 clausule:

SELECT 
    tv.*,ep.* 
FROM tv_show tv 
CROSS APPLY (
    SELECT TOP 1 * FROM tv_episodes 
     WHERE t_id = tv.id 
     ORDER BY episode_num DESC 
) ep 
+0

感謝您的回答,但它不會用我的版本。 – 2010-10-04 16:54:46

0

UPDATE:試試這個 -

Select tv.name as Tv_Show_Name,Max(episode_num) as Latest_Episode_Number from tv_show tv inner join tv_episode te 
on tv.id=te.t_id 
group by te.t_id,tv.name,episode_num 
+0

謝謝你的回答。 ,但我想從每個電視節目「按照」電視節目分組的最新情節。 – 2010-10-04 16:55:28

+0

謝謝你的輸入,但它並沒有給出獨特的電視節目 – 2010-10-04 17:06:53

+0

嗯..我的朋友沒有我的電腦上的MySQL測試...我改變了我的查詢一點點..看它是否工作...但它應該要直截了當......並且不要像你一樣加入兩次.. – Vishal 2010-10-04 17:10:12

0

試試這個:

SELECT tv.*,ep.* FROM tv_show tv 
INNER JOIN episodes ep ON (tv.id = ep.t_id) 
WHERE ep.episode_num > ALL(SELECT x.episode_num FROM tv_episodes x WHERE x.episode_num != ep.episode_num) 
1

查詢性能不僅僅是查詢結構的功能,還包括在基礎表上定義了哪些索引。

+0

你可以看到索引,可以有任何改進嗎? – 2010-10-04 17:00:39