將一個大查詢分成多個較小的查詢會更好嗎?
在某些情況下,需要有非常大的查詢將多個表與其中的子選擇語句連接在一起以產生所需的結果。
我的問題是,我們是否應該考慮使用多個較小的查詢,並通過在多個呼叫中查詢數據庫來將邏輯操作帶入應用程序層,或者最好一次性將它們全部包含在內?
例如考慮以下查詢:
SELECT * FROM `users` WHERE `user_id` IN (SELECT f2.`friend_user_id` FROM `friends` AS f1 INNER JOIN `friends` AS f2 ON f1.`friend_user_id` = f2.`user_id` WHERE f2.`is_page` = 0 AND f1.`user_id` = "%1$d" AND f2.`friend_user_id` != "%1$d" AND f2.`friend_user_id` NOT IN (SELECT `friend_user_id` FROM `friends` WHERE `user_id` = "%1$d")) AND `user_id` NOT IN (SELECT `user_id` FROM `friend_requests` WHERE `friend_user_id` = "%1$d") AND `user_image` IS NOT NULL ORDER BY RAND() LIMIT %2$d
最好的方法是什麼?
我將不同意在這裡使用 datagod 進行的大型複雜查詢。如果它們雜亂無章,我只會將它們視為問題。在性能方面,這些幾乎總是更好,因為規劃者在如何檢索資訊方面有更多的自由。但是,在編寫大型查詢時確實需要考慮到可維護性。總的來說,我發現即使單個查詢持續 200 多行,簡單、結構良好的 SQL 也很容易調試。這是因為通常您非常清楚自己正在處理什麼樣的問題,因此您只需檢查查詢中的幾個區域。
當 SQL 的結構發生故障時,IME 的維護問題就會出現。子選擇中的長而復雜的查詢會損害可讀性和故障排除,內聯視圖也是如此,在長查詢中應該避免這兩種情況。相反,如果可以,請使用 VIEW(請注意,如果您在 MySQL 上,視圖的性能不會那麼好,但在大多數其他 db 上卻可以),並在那些不起作用的地方使用公共表表達式(MySQL 不支持這些順便提一句)。
從可維護性和性能方面來看,長的複雜查詢工作得很好,在這種情況下,您可以保持 where 子句簡單,並且您可以盡可能多地使用連接而不是子選擇。目標是讓“記錄不顯示”在查詢中為您提供一些非常具體的位置來檢查(它是在連接中被刪除還是在 where 子句中被過濾掉?),因此維護團隊居然可以保養東西。
關於可擴展性,請記住,規劃者的靈活性越大,這也是一件好事……
編輯:你提到這是 MySQL,所以視圖不太可能表現得那麼好,CTE 是不可能的。此外,給出的範例不是特別長或特別複雜,因此沒問題。