【问题标题】:fix Using index, Using temporary, Using filesort修复使用索引,使用临时,使用文件排序
【发布时间】:2014-06-07 09:08:54
【问题描述】:

我有这样 3 张桌子。我试图离开加入他们

    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;

SELECT EXPLAIN 告诉我

t_newsrelations 是中间表。表t_categories 包含由 parent_id 列链接的类别和子类别。 t_news 中的每个项目都可以是多个子类别的成员,这就是它们通过 t_newsrelations 链接的原因

如何优化查询?为什么它显示使用索引,使用临时,使用文件排序?

【问题讨论】:

  • 您只有 27 条记录?
  • 这是暂时的,我还没有启用网站的生产模式
  • 但是您确实意识到 EXPLAIN 依赖于数据库统计信息?使用不同填充的数据库的相同查询可能会产生不同的 EXPLAIN。当表很小时,一些引擎会完全忽略索引,只是按顺序读取表。如果您没有真实或真实的数据(恕我直言),则无法真正优化数据库。

标签: mysql sql join explain


【解决方案1】:
ORDER BY `t`.`position`,`st`.`position`,`n`.`position` ASC

鉴于您拥有的表,您无法在此查询中消除临时表和文件排序,因为您正在对来自多个表的列进行排序。优化排序意味着使用索引,以便查询按照您想要的顺序获取行。但是在 MySQL 中没有办法创建跨多个表的索引。

解决此问题的唯一方法是进行非规范化,直到所有三列都在一个表中,然后在三列上创建一个索引。但非规范化有其自身的缺点。

【讨论】:

    猜你喜欢
    • 2015-02-23
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2016-09-04
    • 2012-11-17
    • 2011-06-23
    • 2016-09-27
    • 1970-01-01
    相关资源
    最近更新 更多