[请益] 一页的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