繁体   English   中英

子查询的目的

[英]Purpose of sub-query

我正在处理一个需要优化查询的维护项目。 这是一个非常复杂的查询,所以我分为 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

结果集是您的documents表的子集。

接下来,主查询的FROM

FROM ( /* that subquery up there ^^^ */ ) this

这会将子查询的虚拟表的结果集,并赋予它this一个名字。 MySQL 的查询优化器通常足够聪明,可以避免这种子查询模式的额外开销。

接下来,我们将看看SELECT

SELECT SQL_CALC_FOUND_ROWS 
       this.* , 
       COUNT(this.document_id) as count_document_id
 FROM ...

SQL_CALC_FOUND_ROWS在这里弃用且毫无意义,但它没有坏处。 它已被弃用,因为有更好的方法来计算行数。 这是毫无意义的,因为这个查询必须只返回一行; 继续阅读。

COUNT(this.document_id) as count_document_id计算来自包含非 NULL document_id 的子查询的所有行。 但是document_id是底层表的主键,所以它永远不会为空。 因此COUNT(*)也能正常工作。 而且,顺便说一下,它使子查询的ORDER BY子句完全没有意义。

因为在 SELECT 行上有一个聚合函数并且没有 GROUP BY 子句,所以查询聚合了子查询中的所有行并只产生一行。

this.*在标准 SQL 中是完全错误的。 它在 MySQL 中毫无意义:您从该查询返回的单行包含计数:很好。 但是通过指定this.*您还可以从子查询中返回一个随机选择的行的内容。 当您迁移到 MySQL 8.0 时,这将中断。 MySQL 对 GROUP BY 有一个臭名昭著的非标准扩展,它支持这种随机的事情。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM