2

入れ子集合モデルで使用するインデックスを理解するのに問題があります。クエリは次のとおりです。

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

このクエリは、で最大5000行で約350ミリ秒かかりますcategories。EXPLAINはこれを与えます:

1 SIMPLE filebank_categories ref fk_filebank_categories_categories1、filebank_id filebank_id 5const474使用場所; 一時的な使用; filesortの使用
1SIMPLEノードeq_refPRIMARY、lft、category、cat、lft、rgt、system、id、lft、system PRIMARY 4 filebank_categories.category_id 1    
1 SIMPLE parent ref lft、category、system system 5node.system_id50使用場所
1 SIMPLE category_names eq_ref PRIMARY、fk_categories_names_categories1 PRIMARY 8 node.id、const1ここでの使用

テーブル構造:

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;

これを改善する方法はありますか?それも可能ですか?私はデータベースの最適化の経験があまりないので、ここで使用するインデックス(およびその理由)を実際に理解することはできません。

ありがとう。

4

1 に答える 1

5

次のように、を移動し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`),
  ...
);
于 2010-12-13T16:27:47.517 に答える