[請益] 一頁的db query數

作者: asleepme (500年沒換暱稱了)   2018-09-17 12:39:31
想請教一下,讀取一頁的時候 db 的query 次數會是一個重要的考量嗎?
效能、維護性、安全性等等
db server跟app server是不同主機,每個query也不複雜
假設有2個做法
A. 透過3-4個query,table 拉回來的資料就是可以直接用的
B. 把多個table join成一個query,一次把資料拉回來
然後程式邏輯需要在處理一下,這個程式邏輯也不複雜
A跟B哪個做法比較好,會有差異嗎?
作者: shvanta (vant)   2018-09-17 12:48:00
個人認為B的做法較好,一方面減少HTTP Request數,一方面DB對常用SQL,其實是有自己的機制讓運行加快
作者: gmoz ( This can't do that. )   2018-09-17 12:59:00
次數跟資料量之間的平衡
作者: alan3100 (BOSS)   2018-09-17 13:11:00
會問這問題就選A. 你分不清楚A和B差異,選B對後人80%賽康
作者: oopFoo (3d)   2018-09-17 13:11:00
要B的話,就直接改用redis。以前是用memcached
作者: asleepme (500年沒換暱稱了)   2018-09-17 14:32:00
請教alan大,其中的差異跟B造成康的原因是什麼?感謝~
作者: BignoZe (BignoZe)   2018-09-17 14:46:00
A 對 db 效能較好,B 可做的事情較多。 複雜的需求B,簡單的需求 A,試著用 explain 指令看看 db 實際搜尋的方法和搜尋的資料筆數來判斷。這邊是如果資料量大才需要考慮如果資料量小,過早的最佳化是一個反模式
作者: skitty (aki)   2018-09-17 14:49:00
可能出來ABCD 半年後說C資料有錯 後人要連ABD一起看
作者: BignoZe (BignoZe)   2018-09-17 14:54:00
較複雜的話可以寫測試 很容易寫的 要錯也難
作者: testPtt (測試)   2018-09-17 15:02:00
declare 去拆分需要的 少用多重join
作者: BignoZe (BignoZe)   2018-09-17 19:36:00
table設計怪怪的 table A user_id, object_id 是 uniq那 table Y 可以直接關聯 foriegn key x_id這邊統計要回歸你的需求 你要統計的是什麼值 感覺上是可先 join 再用 group 和 count 做運算統計的話就不用管效能了 怎麼弄都是 slow query
作者: TAKADO (朕沒給的你不能搶)   2018-09-17 20:55:00
通常是B,但沒有標準答案吧,要看應用場景。B沒寫好很容易讓DB炸掉,尤其當join其中一張是上百萬千萬筆的資料表。
作者: asleepme (500年沒換暱稱了)   2018-09-17 22:22:00
感謝大家對db相關的指導~ 至於應用.. 剛剛改變了 XD
作者: alog (A肉哥)   2018-09-17 22:36:00
基本上要看你的瓶頸是什麼 再來決定優化手段
作者: crossdunk (推噓自如)   2018-09-17 22:36:00
看資料量吧
作者: alog (A肉哥)   2018-09-17 22:39:00
如果那頁是高流量 or 該頁 request 數量1秒內是所有頁面request數平均的好幾倍 你就勢必要做調整不論是利用 data/view/page cache 等AB 作法要看多利用 EXPLAIN 指令來看 SQL引擎怎麼解讀你的指令 未必快或慢Query 越多意味著 application 跟 database server 之間的傳輸封包量也會多 資料量也是如果你的 query 結果沒有被 db query cache 起來其實也不會快 不過有些情況是得關掉的總之 如果你要單純比較 A 跟 B 我還是要先問 你的瓶頸在哪裡因為如果要做極致優化 有時候是連 select 的內容都會計較但問題是 還是要回歸一開始你的瓶頸在哪裡 有沒有要事先預防或安排 再來針對那個問題做優化 而不是每頁都一定要做點什麼只要掌握一個小規矩 就是別沒事搞出N+1的狀況就好
作者: viper9709 (阿達)   2018-09-17 22:53:00
這個要看情況~不過一般來說A對DB的負擔比較輕
作者: ernieyang09 (亂入)   2018-09-17 23:50:00
不複雜串幾張表sum一下的可以用B 要跨很多表統計的我會選A orm裡面的select_related跟prefetch也看情況用
作者: alan3100 (BOSS)   2018-09-18 00:34:00
你一開始說分開query可以直接使用,且延伸問題看起來也沒join的必要. 除非你有要readlock不然沒必要一起拉with q_X as ( select ... from X where user_id=1),q_Y as ( select object_id, ... from Ywhere user_id=1 group by object_id)select * from q_X left join q_Yon q_X.object_id = q_Y.object_id要硬湊大概就長這樣, executionplain理論上跟原本差不多
作者: testPtt (測試)   2018-09-18 09:23:00
他的問題應該在於不知道怎麼接收多重select回傳的結果所以用新手方法把select分批送出 這跟寫sql的功力無關了
作者: abc0922001 (中士abc)   2018-09-18 10:51:00
跟DB連線很貴的,次數要降到最小
作者: alan3100 (BOSS)   2018-09-18 11:12:00
那是沒用pool 。連這個都沒有就太誇張
作者: srwhite (魯蛇阿白)   2018-09-18 12:09:00
不用考慮效能的情況下大家會不會覺得A比較好維護
作者: asleepme (500年沒換暱稱了)   2018-09-18 12:12:00
我覺得我們需要DB專板 XD
作者: stevekevin10 (hippo泡)   2018-09-18 12:17:00
一般狀況下請用2
作者: BignoZe (BignoZe)   2018-09-18 21:40:00
沒錯 有 connection pool 的情況下不會有 request 好幾次的問題 統計需求多變 執行次數不多 除非量真的大到跑不動的情況 可以用簡單的方法實作出來比較重要

Links booklink

Contact Us: admin [ a t ] ucptt.com