Mysql 子查询的目的

Mysql 子查询的目的,mysql,Mysql,我正在进行一个维护项目,需要优化查询。这是一个非常复杂的查询,所以我分为5个部分 在一个表“文档”中,字段位于 document_id(PK) doc_name fk_product_id issue_date date_expiring status 疑问是 SELECT SQL_CALC_FOUND_ROWS this.* , COUNT(this.document_id) as count_document_id, FROM ( SELECT * from documents where

我正在进行一个维护项目,需要优化查询。这是一个非常复杂的查询,所以我分为5个部分

在一个表“文档”中,字段位于

document_id(PK)
doc_name
fk_product_id
issue_date
date_expiring
status
疑问是

SELECT SQL_CALC_FOUND_ROWS this.* , COUNT(this.document_id) as count_document_id,
FROM ( SELECT * from documents where status != 'D' order by date_expiring desc ) this 
有数百万条记录,但上面的查询只返回记录。我不明白这个查询是什么意思/它将返回什么记录。

让我们把它分解一下

从子查询开始:

SELECT * FROM documents WHERE status != 'D' ORDER BY date_expiring desc
FROM ( /* that subquery up there ^^^ */ ) this
SELECT SQL_CALC_FOUND_ROWS 
       this.* , 
       COUNT(this.document_id) as count_document_id
 FROM ...
结果集是
文档
表的子集

接下来,主查询的FROM

SELECT * FROM documents WHERE status != 'D' ORDER BY date_expiring desc
FROM ( /* that subquery up there ^^^ */ ) this
SELECT SQL_CALC_FOUND_ROWS 
       this.* , 
       COUNT(this.document_id) as count_document_id
 FROM ...
这将子查询的结果集视为一个虚拟表,并为其提供名称
This
。MySQL的查询优化器通常足够聪明,可以避免这种子查询模式带来的额外开销

接下来,我们将查看选择

SELECT * FROM documents WHERE status != 'D' ORDER BY date_expiring desc
FROM ( /* that subquery up there ^^^ */ ) this
SELECT SQL_CALC_FOUND_ROWS 
       this.* , 
       COUNT(this.document_id) as count_document_id
 FROM ...
SQL\u CALC\u FOUND\u ROWS
在这里,但它没有什么害处。不推荐使用它,因为有更好的方法来计算行数。这是毫无意义的,因为这个查询必须只返回一行;继续读下去

COUNT(this.document\u id)as COUNT\u document\u id
统计子查询中包含非空文档\u id的所有行。但是
document\u id
是基础表的主键,因此它永远不会为空。因此,
COUNT(*)
也同样有效。顺便说一句,它使得子查询的
orderby
子句毫无意义

因为SELECT行上有一个GROUPBY子句,而没有GROUPBY子句,所以查询聚合子查询中的所有行并只生成一行

这个。*
在标准SQL中完全是错误的。在MySQL中这是没有意义的:从这个查询返回的一行包含计数:没关系。但是通过指定
this.*
您还可以从子查询中仅返回随机选择的一行的内容。当您移动到MySQL 8.0时,这将中断。这使得这类随机事件成为可能

我希望这有帮助。接管某人的代码可能很有趣,嗯?

COUNT()
执行隐藏分组并将整个行集作为单个组处理。因此,输出行集包含一行。