我正在使用MySQL。我想插入属于具有不同级别(root_id,lft,rgt,level)的嵌套集模型的100.000个位置。如果我不必担心这棵树,我会做一个大量插入;但在这种情况下,我必须为此订单上的每个对象执行3次查询:
foreach ( $places as $place )
{
# get parent place from $ancestor_array ( woeid => ids )
$parent = $ancestors[:parent_woeid]
update place set lft = lft + 2 where root_id = :root_id and lft >= :obj_lft;
update place set rgt = rgt + 2 where root_id = :root_id and rgt >= :obj_lft;
insert into place (..., root_id, lft, rgt, level, ...) values (..., :obj_root_id, :obj_lft, :obj_rgt, :obj_level, ...);
...
}
这需要很长时间......所以是时候尝试变得更聪明了。这就是我的想法:
foreach ( $places as $place )
{
# get parent place from $ancestor_array ( woeid => ids )
$parent = $ancestors[:parent_woeid]
$new_admins[] = array('parent_woeid' => :parent_woeid, ...data place....)
$woeids[] = :parent_woeid;
}
# lock + bulk insert of $new_admins with lft=rgt=level=root_id= null + unlock
insert into place (...) values (...), (...), (...), ...., (...)
# get ids of those places
select from place where woeid in(:array_woeids)
# lock + bulk update with 3 updates per place + unlock
update place set lft= lft + 2 where root_id = :root_id and lft >= :obj_lft;
update place set rgt = rgt + 2 where root_id = :root_id and rgt >= :obj_lft;
update place set lft=:obj_lft, rgt=:obj_rgt where id=:id
# i have to update the ancestors lft & rgt values on the $ancestors_array,
# because we have them "cached" in the array in order to avoid doing a
# select per inserted place.
你怎么看?你会怎么做?您是否将所有插入和更新保存到文件中并使用LOAD DATA INFILE
语法而不是此选项?
我还缺少其他选项吗?
非常感谢!
答案 0 :(得分:3)
仅在插入所有项目时插入项目并重新计算所有lft / rgt索引不是更有效吗?
但是要做到这一点,你必须知道每个项目的父ID,所以你有一些基于索引的东西。我个人成功地将lft + lrg + parentId与每个数据项保持一致,这使得维护变得更加容易(您可以随时进行琐碎的重新计算/完整性检查)。