簡體   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