I have an application that needs to update nodes in a hierarchical structure, up from a specific node whose identifier is known. For this, I use the following MySQL statement:
update node as A join node as B on A.lft<=B.lft and A.rgt>=B.rgt set A.count=A.count+1 where B.id=?
The table has a primary key on id and indexes on lft and rgt. The statement works, but I found that it had performance issues. If you look at the EXPLAIN results for the corresponding select statement, I saw that the number of rows checked for table "B" was very large (possibly the whole table).
I can easily split the request into two separate parts:
select lft, rgt from node where id=? LFT=result.lft RGT=result.rgt update node set count=count+1 where lft<=LFT and rgt>=RGT
But why doesn't the original statement work as expected, and how do I need to reformulate it for better performance?
Upon request, an abridged version of the create table is provided here:
CREATE TABLE `node` ( `id` int(11) NOT NULL auto_increment, `name` varchar(255) NOT NULL, `lft` decimal(64,0) NOT NULL, `rgt` decimal(64,0) NOT NULL, `count` int(11) NOT NULL default '0', PRIMARY KEY (`id`), KEY `name` (`name`), KEY `location` (`location`(255)), KEY `lft` (`lft`), KEY `rgt` (`rgt`), ) ENGINE=InnoDB
I did not try to add a composite index (in fact, I do not have the access level necessary for this on the spot); but I don’t understand how this will help, trying to understand how the database engine will try to solve the dual inequality.