Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
嵌套mysql查询的性能损失_Mysql_Nested - Fatal编程技术网

嵌套mysql查询的性能损失

嵌套mysql查询的性能损失,mysql,nested,Mysql,Nested,从表中选择*与从表中选择*相比,从表中选择*的性能损失是多少 我的问题是:首先,SELECT*是否涉及对表中的行进行迭代,或者它只是将所有行作为块返回而不进行任何迭代,因为没有给出WHERE子句,如果是这样,那么示例2中的嵌套查询是否涉及对表进行两次迭代,并且将花费第一次查询的2倍时间?谢谢……这个问题的答案取决于您使用的是5.7之前还是5.7之后的mysql。我可能会稍微改变你的问题,但希望下面能抓住你想要的 SELECT*FROM表通过聚集索引和物理排序执行表扫描。如果没有主钥匙,发动机可以

从表中选择*与从表中选择*相比,从表中选择*的性能损失是多少


我的问题是:首先,SELECT*是否涉及对表中的行进行迭代,或者它只是将所有行作为块返回而不进行任何迭代,因为没有给出WHERE子句,如果是这样,那么示例2中的嵌套查询是否涉及对表进行两次迭代,并且将花费第一次查询的2倍时间?谢谢……

这个问题的答案取决于您使用的是5.7之前还是5.7之后的mysql。我可能会稍微改变你的问题,但希望下面能抓住你想要的

SELECT*FROM表通过聚集索引和物理排序执行表扫描。如果没有主钥匙,发动机可以使用一把主钥匙。没有你说的where子句。未尝试筛选或选择其他索引

输出see在其摘要中显示1行。这是比较直截了当的。根据您使用的是5.7之前的版本,还是5.7之后的版本,派生表B的解释输出和性能将有所不同

该文档对版本5.6和5.7进行了很好的描述,其中后者不会因为将具体化的派生表输出合并到外部查询中而带来任何损失。在以前的版本中,派生的临时表承受了巨大的开销

在5.7之前测试性能惩罚非常容易。只需要一个中等大小的表就可以看到问题的派生表对性能的显著影响。以下示例位于5.6版中的一个小表格上:

explain 
select qm1.title  
from questions_mysql qm1 
join questions_mysql qm2 
on qm2.qid<qm1.qid 
where qm1.qid>3333 and qm1.status='O';
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
| id | select_type | table | type  | possible_keys   | key     | key_len | ref  | rows  | Extra                                          |
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+
|  1 | SIMPLE      | qm1   | range | PRIMARY,cactus1 | PRIMARY | 4       | NULL |  5441 | Using where                                    |
|  1 | SIMPLE      | qm2   | ALL   | PRIMARY,cactus1 | NULL    | NULL    | NULL | 10882 | Range checked for each record (index map: 0x3) |
+----+-------------+-------+-------+-----------------+---------+---------+------+-------+------------------------------------------------+


explain 
select b.title from 
(   select qid,title from questions_mysql where qid>3333 and status='O' 
) b 
join questions_mysql qm2 
on qm2.qid<b.qid; 
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
| id | select_type | table           | type  | possible_keys   | key     | key_len | ref  | rows  | Extra                                              |
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+
|  1 | PRIMARY     | qm2             | index | PRIMARY,cactus1 | cactus1 | 10      | NULL | 10882 | Using index                                        |
|  1 | PRIMARY     | <derived2>      | ALL   | NULL            | NULL    | NULL    | NULL |  5441 | Using where; Using join buffer (Block Nested Loop) |
|  2 | DERIVED     | questions_mysql | range | PRIMARY,cactus1 | PRIMARY | 4       | NULL |  5441 | Using where                                        |
+----+-------------+-----------------+-------+-----------------+---------+---------+------+-------+----------------------------------------------------+

请注意,我确实改变了这个问题,但它说明了在5.7之前的版本中,派生表及其与优化器的索引使用不足所产生的影响。派生表在具体化时受益于索引。但此后,它作为一个临时表承受着开销,并被合并到外部查询中,而不使用索引。版本5.7中的情况并非如此。很好的解释:在性能方面,在两个子查询之间的联接操作中,是否更倾向于在内部查询中指定LIMIT子句,而不是在外部查询中指定LIMIT子句?例如:从表1中选择id限制10作为自然联接表2比从表1中选择id作为自然联接表2限制10更好这可能包含一些与表命名相关的语法错误,但是。。。?谢谢:最好在您的服务器版本、您的模式上使用它。以下是在非服务器级笔记本电脑上启用的。注意,我从不使用自然连接。我尽量不作笼统的回答。尤其是在解释可能看起来相同的输出时。这在堆栈上发生得太多了。因此,相反,将我们的查询指向更大的数据集,并对性能最差的查询或一般调查执行至少15分钟的测试,如。性能将因优化器的版本而异。