【问题标题】:Nested Set indices & performance嵌套集索引和性能
【发布时间】:2011-05-24 15:49:56
【问题描述】:

我在理解在嵌套集模型上使用哪些索引时遇到了一些麻烦。查询是:

SELECT `node`.`id`,(COUNT(parent.id) - 1) AS `depth`,`name` FROM `categories` AS `parent` 
INNER JOIN `categories` AS `node` ON (`node`.`lft` BETWEEN parent.lft AND parent.rgt)
INNER JOIN `filebank_categories` ON (`node`.`id` = `filebank_categories`.`category_id` AND `filebank_categories`.`filebank_id` = 136)
INNER JOIN `categories_names` ON (`categories_names`.`category_id` = `node`.`id` AND `categories_names`.`language_id` = 1) 
WHERE `node`.`system_id` = parent.system_id 
GROUP BY node.id 
ORDER BY `node`.`lft` ASC

此查询耗时约 350 毫秒,categories 中有约 5000 行。 EXPLAIN 给出了这个:

1 SIMPLE filebank_categories ref fk_filebank_categories_categories1,filebank_id filebank_id 5 const 474 使用 where;使用临时的;使用文件排序 1 SIMPLE 节点 eq_ref PRIMARY,lft,category,cat,lft,rgt,system,id,lft,system PRIMARY 4 filebank_categories.category_id 1 1 SIMPLE parent ref lft,category,system system 5 node.system_id 50 使用 where 1 SIMPLE categories_names eq_ref PRIMARY,fk_categories_names_categories1 PRIMARY 8 node.id,const 1 使用 where

表结构:

CREATE TABLE `categories` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `system_id` int(11) DEFAULT NULL,
  `lft` int(11) DEFAULT NULL,
  `rgt` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `lft,category` (`lft`,`id`),
  KEY `cat,lft,rgt` (`id`,`lft`,`rgt`),
  KEY `system` (`system_id`),
  CONSTRAINT `categories_ibfk_1` FOREIGN KEY (`system_id`) REFERENCES `systems` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11519 DEFAULT CHARSET=utf8;

任何想法如何改善这一点?甚至可能吗?我在数据库优化方面不是很有经验,所以我无法真正弄清楚在这里使用什么索引(以及为什么)。

谢谢。

【问题讨论】:

    标签: mysql query-optimization nested-sets


    【解决方案1】:

    你可以尝试移动WHERE clause加入,点赞

    SELECT ...
    INNER JOIN `categories` AS `node` ON 
    (
      node.system_id=parent.system_id AND 
      node.lft BETWEEN parent.lft AND parent.rgt
    )
    

    并将索引细化为:

    CREATE TABLE `categories` (
      ...
      KEY `system_id,lft,rgt` (`system_id`,`lft`,`rgt`),
      ...
    );
    

    【讨论】:

    • +1 表示索引,旧的 KEY cat,lft,rgt (id,lft,rgt) 无法比较;此外,您可能希望停止在键名中使用逗号 - 这使得在查询计划中读取可能的键成为一项有趣的练习。
    • 谢谢!这有帮助,查询现在在大约 100 毫秒内运行。但是对于“filebank_categories”,我仍然得到“使用临时;使用文件排序”,我认为这是最减慢一切的原因?
    • filesort没问题(filesort的名字不太准确),使用临时是分组造成的
    猜你喜欢
    • 1970-01-01
    • 2011-03-24
    • 2011-08-30
    • 2011-10-12
    • 1970-01-01
    • 2020-02-25
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多