【发布时间】:2013-09-18 11:37:21
【问题描述】:
我有一个应用程序需要更新分层结构中的节点,从已知 ID 的特定节点向上更新。我使用以下 MySQL 语句来执行此操作:
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=?
该表在 id 上有一个主键,在 lft 和 rgt 上有一个索引。该语句有效,但我发现它存在性能问题。查看对应 select 语句的 EXPLAIN 结果,我看到为“B”表检查的行数非常大(可能是整个表)。
我可以轻松地将查询分成两个独立的:
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
但是为什么原始语句没有按预期执行,我需要如何重新制定它才能更好地工作?
根据要求,这里是创建表的缩写版本:
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
我没有尝试添加复合索引(实际上,我没有当场执行此操作所需的访问级别);但我看不出它有什么帮助,试图思考数据库引擎将如何尝试解决双重不等式。
【问题讨论】:
-
如果您可以同时发布表定义和解释,这将有所帮助...
-
你能发布
CREATE TABLE语句和`EXPLAIN 输出吗? -
顺便说一句:
A.lft<=B.lft and A.rgt>=B.rgt的条件对于A==B为真。这是预期的行为吗? -
是的,这是故意的 :-)
-
表是 MyISAM 还是 InnoDB?
标签: mysql sql performance join