我正在閱讀有關如何解釋 EXPLAIN 計劃結果的 MySQL檔案。我在頂部看到以下段落:
EXPLAIN 為 SELECT 陳述句中使用的每個表回傳一行資訊。它按照 MySQL 在處理陳述句時讀取它們的順序列出輸出中的表。這意味著 MySQL 從第一個表中讀取一行,然后在第二個表中找到匹配的行,然后在第三個表中,以此類推。處理完所有表后,MySQL 會輸出選定的列并通過表串列回溯,直到找到匹配行較多的表。從此表中讀取下一行,并繼續處理下一個表。
如果我的解釋正確,這意味著可以通過將每個表的“行”部分中找到的數量相乘來估計查詢結果中最壞情況的行數,因為如果表 1 的每一行都可能有一個表 2 的行等
作為說明,這是我正在嘗試除錯的查詢:
SELECT DISTINCT DISTINCT roles.id, roles.*
FROM `roles`
INNER JOIN `resources`
ON `resources`.`role_id` = `roles`.`id`
INNER JOIN `resources` `workspace_resources_roles`
ON `workspace_resources_roles`.`role_id` = `roles`.`id`
AND `workspace_resources_roles`.`type`
IN ('WorkspaceResource')
INNER JOIN workspaces
ON resources.subject_id = workspaces.id
AND resources.subject_type = "Workspace"
WHERE `roles`.`account_id` = 6804175
AND `roles`.`deleted_at` IS NULL
AND `resources`.`type` = 'WorkspaceResource'
AND `resources`.`user_id` IS NULL
AND `workspaces`.`archived` = FALSE
AND `workspaces`.`account_id` = 6804175
AND `roles`.`id` = 1205685
ORDER BY roles.name ASC
這是它的解釋計劃:
id 1
select_type SIMPLE
table roles
partitions NULL
type const
possible_keys PRIMARY,index_roles_on_account_id_and_deleted_at_and_name,index_roles_on_account_id
key PRIMARY
key_len 4
ref const
rows 1
filtered 100.0
Extra Using temporary
id 1
select_type SIMPLE
table resources
partitions NULL
type index_merge
possible_keys index_resources_on_user_id,index_resources_on_role_id,index_resources_on_type,index_resources_on_subject_id_and_subject_type,index_resources_on_subject_id
key index_resources_on_role_id,index_resources_on_user_id
key_len 5,5
ref NULL
rows 4075
filtered 2.5
Extra Using intersect(index_resources_on_role_id,index_resources_on_user_id); Using where; Distinct
id 1
select_type SIMPLE
table workspaces
partitions NULL
type eq_ref
possible_keys PRIMARY,index_workspaces_on_account_id
key PRIMARY
key_len 4
ref mavenlink_production.resources.subject_id
rows 1
filtered 5.0
Extra Using where; Distinct
id 1
select_type SIMPLE
table workspace_resources_roles
partitions NULL
type ref
possible_keys index_resources_on_role_id,index_resources_on_type
key index_resources_on_role_id
key_len 5
ref const
rows 32620
filtered 50.0
Extra Using where; Distinct
表 1 有 1 行,表 2 有 4075 行,表 3 有 1 行,表 4 有 32,620 行。在最壞的情況下,這是否意味著 1 * 4,075 * 1 * 32,620 = 132,936,500 行的總結果集?如果是這樣,這就解釋了為什么這個查詢在我們的生產環境中需要 173 秒。
uj5u.com熱心網友回復:
您在解釋 EXPLAIN 方面走在了正確的軌道上。您有一個沒有子查詢的簡單查詢,并且您將rows每個連接表的相乘。根據優化器計算的估計,這大致是要檢查的行數。
請注意,優化器的估計非常粗略。不要認為它們是精確的。
如果您有子查詢,或者如果您使用LIMIT,則這種解釋檢查行的方法會變得更加復雜。
如果你想要一個真實的測量,而不是來自 EXPLAIN 的估計,那么執行查詢(不使用 EXPLAIN),然后運行SHOW SESSION STATUS LIKE 'Handler%';. 它將向您顯示存盤引擎運行的操作的確切數量。像 Handler_read_next 或 Handler_read_rnd 這樣的操作對應于檢查的行。FLUSH STATUS在測驗之間運行以將會話狀態值清零。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/409065.html
標籤:
