我想在一个MySQL表中存储多个MPTT(Modified Preorder Travelsal Trees),其中包含以下列: node_id,user_id,rht,lft,value 。单树被分配给网站上的单个用户。
要为我将使用的用户选择指定节点的树:
SELECT * FROM categories
WHERE user_id = 123
AND lft > node_lft
AND rht < node_rht;
我考虑对此函数使用嵌套查询:
SELECT t.* FROM
(SELECT * FROM categories WHERE user_id = 123) t
WHERE lft > node_lft
AND rht < node_rht;
在大数据上运行时哪些查询更快(例如10000个用户,每个人都有一个具有随机深度和元素数量的树)以及为什么?
答案 0 :(得分:2)
除非你有充分的理由,否则不要在MySQL的FROM
子句中使用嵌套子查询。 MySQL实现了这样的子查询。除了开销之外,它还可以防止使用索引进行连接。
相反,只需在表上定义正确的索引即可。根据您的查询:
categories(user_id, lft, rht)
答案 1 :(得分:0)
任何以user_id
开头的索引都将对任一查询都有益。请提供SHOW CREATE TABLE
。
没有子查询:
INDEX(user_id, lft)
(或INDEX(user_id, rht)
)可能会扫描user_id=123
行的一半;比INDEX(user_id)
更小的改进。由于“范围”(lft > nodelft
),(user_id, lft, rht)
,3列索引确实超出了lft
的范围;因此没有益处。
使用子查询:
user_id=123
提取所有行;放入tmp表。子查询不能更快。如果是,则可能是在执行时序测试时缓存的内容存在差异。
桌子有多大?缓存有多大(如果是InnoDB,innodb_buffer_pool_size
)?如果表太大,则可能需要“延迟查找”。
您是否使用node_id
进行任何操作?这个组合是唯一的:(user_id, lft, rht)
;如果是这样的话可能是PRIMARY KEY
。 (通过PK我们访问通常比通过InnoDB中的二级密钥更快。)