我有一個 mysql 查詢,它結合了來自 3 個表的資料,我稱之為“first_table”、“second_table”和“third_table”,如下所示。
此查詢始終顯示在 MySQL 慢查詢日志中,即使查詢中參考的所有欄位都已編入索引,并且這些表中的實際資料量并不大(< 1000 條記錄,但“third_table”除外,它有更多的類似 10,000記錄)。
我正在嘗試確定是否有更好的方法來構建此查詢以實作更好的性能,以及此查詢的哪一部分最有可能是導致速度下降的罪魁禍首。
請注意,“third_table.placements”是 JSON 欄位型別。所有“label”欄位都是 varchar(255),“id”欄位是主鍵整數欄位,“sample_img”是整數,“guid”是字串,“deleted”是整數,“timestamp”是日期時間。
SELECT DISTINCT first_table.id,
first_table.label,
(SELECT guid
FROM second_table
WHERE second_table.id = first_table.sample_img) AS guid,
Count(third_table.id) AS
related_count,
Sum(Json_length(third_table.placements)) AS
placements_count
FROM first_table
LEFT JOIN third_table
ON Json_overlaps(third_table.placements,
Cast(first_table.id AS CHAR))
WHERE first_table.deleted IS NULL
AND third_table.deleted IS NULL
AND Unix_timestamp(third_table.timestamp) >= 1647586800
AND Unix_timestamp(third_table.timestamp) < 1648191600
GROUP BY first_table.id
ORDER BY Lower(first_table.label) ASC
LIMIT 0, 1000
uj5u.com熱心網友回復:
最大的問題是這些是不可預測的:
WHERE ... Unix_timestamp(third_table.timestamp) < 1648191600
ORDER BY Lower(first_table.label)
也就是說,不要在函式呼叫中隱藏潛在的索引列。反而:
WHERE ... third_table.timestamp < FROM_UNIXTIME(1648191600)
并使用不區分大小寫COLLATION的first_table.label. 那是任何以_ci. (請提供SHOW CREATE TABLE,以便我指出這一點,并檢查模糊的“所有欄位都被索引”——這通常表明不知道“復合”索引的好處。)
Json_overlaps(...)可能也不是 sargable。但它變得更棘手修復。請解釋一下 json 的結構以及 和 的id型別placements。
你真的需要輸出 1000 行嗎?這對于“分頁”來說是相當大的。
桌子有多大?當表太大而無法快取在 RAM 中時,UUID/GUID 是臭名昭著的。
SELECT DISTINCT同時擁有和可能永遠不會有用GROUP BY。洗掉DISTINCT 可能會通過避免額外的排序來加速查詢。
你真的想要LEFT JOIN,不只是JOIN?(我對查詢的理解不足以做出猜測。)
GROUP BY在你修復了大部分之后,如果你仍然需要幫助,我可能有辦法通過添加一個“派生”表來擺脫它。之后。(然后我可以解決“json_overlaps”的討論。)
請提供EXPLAIN SELECT ...
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/448963.html
上一篇:使用現有字串獲取新欄位
