2014-04-22 25 views
2

我有這樣的3個表。我試着去LEFT JOIN他們修復使用索引,使用臨時的,使用filesort

SELECT `t`.`title` AS `category_title`,`t`.`id` AS `category_id`, `st`.`title` AS 
`subcategory_title`, `st`.`id` AS `subcategory_id`, `st`.`parent_id` AS 
`subcategory_parent`, `n`.`title` AS `news_title`,`n`.`id` AS `news_id` FROM 
`t_categories` `t` LEFT JOIN t_categories AS `st` ON `st`.`parent_id`=t.`id` LEFT JOIN 
t_newsrelations AS `nr` ON `nr`.`category_id`=st.`id` LEFT JOIN t_news AS `n` ON 
`n`.`id`=nr.`news_id` WHERE `t`.`enabled` = 1 AND `n`.`enabled` = 1 AND `n`.`type`!=1 AND 
`n`.`type`!=5 ORDER BY `t`.`position`,`st`.`position`,`n`.`position` ASC 

這裏是表

CREATE TABLE IF NOT EXISTS `t_categories` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `parent_id` int(11) NOT NULL, 
    `title` tinytext NOT NULL, 
    `position` tinyint(4) unsigned NOT NULL DEFAULT '0', 
    `type` tinyint(1) unsigned NOT NULL, 
    `enabled` tinyint(1) unsigned NOT NULL DEFAULT '1', 
    UNIQUE KEY `id` (`id`), 
    KEY `type` (`type`), 
    KEY `parent_id` (`parent_id`), 
    KEY `enabled` (`enabled`), 
    KEY `id_parent_position_enabled` (`id`,`parent_id`,`position`,`enabled`), 
    KEY `position` (`position`), 
    KEY `parent_id_2` (`parent_id`,`enabled`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; 


CREATE TABLE IF NOT EXISTS `t_news` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `title` tinytext NOT NULL, 
    `m_title` tinytext NOT NULL, 
    `url` varchar(2000) NOT NULL, 
    `keywords` text NOT NULL, 
    `description` text NOT NULL, 
    `body` longtext NOT NULL, 
    `position` tinyint(4) unsigned NOT NULL DEFAULT '0', 
    `type` tinyint(1) unsigned NOT NULL, 
    `city_id` int(4) NOT NULL, 
    `quickmenu_enabled` tinyint(1) unsigned NOT NULL DEFAULT '0', 
    `quickmenu` text NOT NULL, 
    `enabled` tinyint(1) unsigned NOT NULL DEFAULT '1', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `id` (`id`), 
    KEY `position` (`position`), 
    KEY `type` (`type`), 
    KEY `city_id` (`city_id`), 
    KEY `url` (`url`(333)), 
    KEY `quickmenu_enabled` (`quickmenu_enabled`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ; 


CREATE TABLE IF NOT EXISTS `t_newsrelations` (
    `category_id` int(11) NOT NULL, 
    `news_id` int(11) unsigned NOT NULL, 
    KEY `category_id` (`category_id`), 
    KEY `news_id` (`news_id`), 
    KEY `category_id_2` (`category_id`,`news_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

的結構,並選擇EXPLAIN顯示我

explain-img t_newsrelations是中間表。表t_categories包含由parent_id列鏈接的類別和子類別。 t_news中的每件商品都可以是多個子類別的成員,這就是爲什麼他們通過t_newsrelations鏈接的原因

如何優化查詢?爲什麼顯示使用索引,使用臨時文件,使用filesort?

+0

您只有27記錄? – Frazz

+0

這是現在,我還沒有啓用生產模式的網站尚未 – Undrooleek

+1

但你確實意識到EXPLAIN取決於數據庫的統計數據?具有不同填充數據庫的相同查詢可以生成不同的EXPLAIN。當表格很小時,一些引擎會完全忽略索引,只是順序讀取表格。如果你沒有真實或現實的數據(恕我直言),你無法真正優化數據庫。 – Frazz

回答

3
ORDER BY `t`.`position`,`st`.`position`,`n`.`position` ASC 

因爲您正在對多個表中的列進行排序,所以在此查詢中,您無法消除此查詢中的臨時表和文件夾。優化排序意味着使用索引,以便查詢以您想要的順序提取行。但是MySQL沒有辦法創建一個跨越多個表的索引。

解決此問題的唯一方法是非規範化,直到所有三列都在單個表中,並在三列上創建一個索引。但非規範化帶來了自身的缺點。

相關問題