使用嵌套查询来提高MySQL

时间:2016-04-08 20:41:36

标签: mysql sql database performance

我想在一个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个用户,每个人都有一个具有随机深度和元素数量的树)以及为什么?

2 个答案:

答案 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的范围;因此没有益处。

使用子查询:

  1. 使用user_id=123提取所有行;放入tmp表。
  2. 扫描该tmp表。没有索引是有用的。
  3. 子查询不能更快。如果是,则可能是在执行时序测试时缓存的内容存在差异。

    桌子有多大?缓存有多大(如果是InnoDB,innodb_buffer_pool_size)?如果表太大,则可能需要“延迟查找”。

    您是否使用node_id进行任何操作?这个组合是唯一的:(user_id, lft, rht);如果是这样的话可能是PRIMARY KEY。 (通过PK我们访问通常比通过InnoDB中的二级密钥更快。)