[請益] 一頁的db query數

看板Soft_Job (軟體人)作者 (500年沒換暱稱了)時間7年前 (2018/09/17 12:39), 7年前編輯推噓12(12048)
留言60則, 16人參與, 7年前最新討論串1/2 (看更多)
想請教一下,讀取一頁的時候 db 的query 次數會是一個重要的考量嗎? 效能、維護性、安全性等等 db server跟app server是不同主機,每個query也不複雜 假設有2個做法 A. 透過3-4個query,table 拉回來的資料就是可以直接用的 B. 把多個table join成一個query,一次把資料拉回來 然後程式邏輯需要在處理一下,這個程式邏輯也不複雜 A跟B哪個做法比較好,會有差異嗎? -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 223.137.234.97 ※ 文章網址: https://www.ptt.cc/bbs/Soft_Job/M.1537159174.A.125.html

09/17 12:48, 7年前 , 1F
個人認為B的做法較好,一方面減少HTTP Request數,一方面DB
09/17 12:48, 1F

09/17 12:49, 7年前 , 2F
對常用SQL,其實是有自己的機制讓運行加快
09/17 12:49, 2F

09/17 12:59, 7年前 , 3F
次數跟資料量之間的平衡
09/17 12:59, 3F

09/17 13:11, 7年前 , 4F
會問這問題就選A. 你分不清楚A和B差異,選B對後人80%賽康
09/17 13:11, 4F

09/17 13:11, 7年前 , 5F
要B的話,就直接改用redis。以前是用memcached
09/17 13:11, 5F

09/17 14:32, 7年前 , 6F
請教alan大,其中的差異跟B造成康的原因是什麼?感謝~
09/17 14:32, 6F

09/17 14:46, 7年前 , 7F
A 對 db 效能較好,B 可做的事情較多。 複雜的需求B,簡
09/17 14:46, 7F

09/17 14:46, 7年前 , 8F
單的需求 A,試著用 explain 指令看看 db 實際搜尋的方法
09/17 14:46, 8F

09/17 14:47, 7年前 , 9F
和搜尋的資料筆數來判斷。這邊是如果資料量大才需要考慮
09/17 14:47, 9F

09/17 14:48, 7年前 , 10F
如果資料量小,過早的最佳化是一個反模式
09/17 14:48, 10F

09/17 14:49, 7年前 , 11F
可能出來ABCD 半年後說C資料有錯 後人要連ABD一起看
09/17 14:49, 11F

09/17 14:54, 7年前 , 12F
較複雜的話可以寫測試 很容易寫的 要錯也難
09/17 14:54, 12F
謝謝大家的建議~ 那延伸一下我的問題好啦,其實主要也是我query寫的不好 T_T 我的狀況如下,就是有2個table X, Y,要把Y做某種運算後跟X join在一起 table部分內容示意圖如下 table X user_id| object_id| attr_a| attr_b 1| 1| a| b (user_id, object_id) 不重複 table Y Y_id| user_id| object_id| content_c | content_d 1| 1| 1| c-1 | d-1 2| 1| 1| c-2 | d-2 3| 1| 1| NULL | d-3 要做的事情就是已知 user_id, 從X找出這個user_id的所有rows 對Y做的則是對同一個 user_id 找出 SELECT COUNT(content_c) / COUNT(content_d) as content_ratio , object_id as object_id FROM `Y` WHERE user_id = '1' group by object_id 然後2個join起來,但是要把那個count divide的結果join起來 一直遇到困難,這種要怎麼join呢? ※ 編輯: asleepme (223.137.234.97), 09/17/2018 15:09:56

09/17 15:02, 7年前 , 13F
declare 去拆分需要的 少用多重join
09/17 15:02, 13F

09/17 19:36, 7年前 , 14F
table設計怪怪的 table A user_id, object_id 是 uniq
09/17 19:36, 14F

09/17 19:37, 7年前 , 15F
那 table Y 可以直接關聯 foriegn key x_id
09/17 19:37, 15F

09/17 19:38, 7年前 , 16F
這邊統計要回歸你的需求 你要統計的是什麼值 感覺上是可
09/17 19:38, 16F

09/17 19:38, 7年前 , 17F
先 join 再用 group 和 count 做運算
09/17 19:38, 17F

09/17 19:39, 7年前 , 18F
統計的話就不用管效能了 怎麼弄都是 slow query
09/17 19:39, 18F

09/17 20:55, 7年前 , 19F
通常是B,但沒有標準答案吧,要看應用場景。B沒寫好很容易
09/17 20:55, 19F

09/17 20:55, 7年前 , 20F
讓DB炸掉,尤其當join其中一張是上百萬千萬筆的資料表。
09/17 20:55, 20F

09/17 22:22, 7年前 , 21F
感謝大家對db相關的指導~ 至於應用.. 剛剛改變了 XD
09/17 22:22, 21F

09/17 22:36, 7年前 , 22F
基本上要看你的瓶頸是什麼 再來決定優化手段
09/17 22:36, 22F

09/17 22:36, 7年前 , 23F
看資料量吧
09/17 22:36, 23F

09/17 22:39, 7年前 , 24F
如果那頁是高流量 or 該頁 request 數量1秒內是所有頁面requ
09/17 22:39, 24F

09/17 22:39, 7年前 , 25F
est數平均的好幾倍 你就勢必要做調整
09/17 22:39, 25F

09/17 22:40, 7年前 , 26F
不論是利用 data/view/page cache 等
09/17 22:40, 26F

09/17 22:41, 7年前 , 27F
AB 作法要看多利用 EXPLAIN 指令來看 SQL引擎怎麼解讀你的
09/17 22:41, 27F

09/17 22:41, 7年前 , 28F
指令 未必快或慢
09/17 22:41, 28F

09/17 22:42, 7年前 , 29F
Query 越多意味著 application 跟 database server 之間的
09/17 22:42, 29F

09/17 22:42, 7年前 , 30F
傳輸封包量也會多 資料量也是
09/17 22:42, 30F

09/17 22:42, 7年前 , 31F
如果你的 query 結果沒有被 db query cache 起來其實也不會
09/17 22:42, 31F

09/17 22:42, 7年前 , 32F
快 不過有些情況是得關掉的
09/17 22:42, 32F

09/17 22:43, 7年前 , 33F
總之 如果你要單純比較 A 跟 B 我還是要先問 你的瓶頸在哪
09/17 22:43, 33F

09/17 22:43, 7年前 , 34F
09/17 22:43, 34F

09/17 22:45, 7年前 , 35F
因為如果要做極致優化 有時候是連 select 的內容都會計較
09/17 22:45, 35F

09/17 22:45, 7年前 , 36F
但問題是 還是要回歸一開始
09/17 22:45, 36F

09/17 22:46, 7年前 , 37F
你的瓶頸在哪裡 有沒有要事先預防或安排 再來針對那個問題
09/17 22:46, 37F

09/17 22:46, 7年前 , 38F
做優化 而不是每頁都一定要做點什麼
09/17 22:46, 38F

09/17 22:48, 7年前 , 39F
只要掌握一個小規矩 就是別沒事搞出N+1的狀況就好
09/17 22:48, 39F

09/17 22:53, 7年前 , 40F
這個要看情況~不過一般來說A對DB的負擔比較輕
09/17 22:53, 40F

09/17 23:50, 7年前 , 41F
不複雜串幾張表sum一下的可以用B 要跨很多表統計的我
09/17 23:50, 41F

09/17 23:51, 7年前 , 42F
會選A orm裡面的select_related跟prefetch也看情況用
09/17 23:51, 42F

09/18 00:34, 7年前 , 43F
你一開始說分開query可以直接使用,且延伸問題看起來也沒
09/18 00:34, 43F

09/18 00:36, 7年前 , 44F
join的必要. 除非你有要readlock不然沒必要一起拉
09/18 00:36, 44F

09/18 00:47, 7年前 , 45F
with q_X as ( select ... from X where user_id=1)
09/18 00:47, 45F

09/18 00:48, 7年前 , 46F
,q_Y as ( select object_id, ... from Y
09/18 00:48, 46F

09/18 00:48, 7年前 , 47F
where user_id=1 group by object_id)
09/18 00:48, 47F

09/18 00:48, 7年前 , 48F
select * from q_X left join q_Y
09/18 00:48, 48F

09/18 00:49, 7年前 , 49F
on q_X.object_id = q_Y.object_id
09/18 00:49, 49F

09/18 00:51, 7年前 , 50F
要硬湊大概就長這樣, executionplain理論上跟原本差不多
09/18 00:51, 50F

09/18 09:23, 7年前 , 51F
他的問題應該在於不知道怎麼接收多重select回傳的結果
09/18 09:23, 51F

09/18 09:26, 7年前 , 52F
所以用新手方法把select分批送出 這跟寫sql的功力無關了
09/18 09:26, 52F

09/18 10:51, 7年前 , 53F
跟DB連線很貴的,次數要降到最小
09/18 10:51, 53F

09/18 11:12, 7年前 , 54F
那是沒用pool 。連這個都沒有就太誇張
09/18 11:12, 54F

09/18 12:09, 7年前 , 55F
不用考慮效能的情況下大家會不會覺得A比較好維護
09/18 12:09, 55F

09/18 12:12, 7年前 , 56F
我覺得我們需要DB專板 XD
09/18 12:12, 56F

09/18 12:17, 7年前 , 57F
一般狀況下請用2
09/18 12:17, 57F

09/18 21:40, 7年前 , 58F
沒錯 有 connection pool 的情況下不會有 request 好幾次
09/18 21:40, 58F

09/18 21:41, 7年前 , 59F
的問題 統計需求多變 執行次數不多 除非量真的大到跑不動
09/18 21:41, 59F

09/18 21:42, 7年前 , 60F
的情況 可以用簡單的方法實作出來比較重要
09/18 21:42, 60F
文章代碼(AID): #1Rdp064b (Soft_Job)
討論串 (同標題文章)
文章代碼(AID): #1Rdp064b (Soft_Job)