iT邦幫忙

0

網站資料庫瓶頸到底是在io 還是在 join

  • 分享至 

  • xImage

在前公司時
如果 join 很多張 table
我們做法是先全部用各自的條件撈出來
在應用層做處理
那時比較資深的同事說
這樣做的目的是為資料庫降壓

但網路上有些文章
https://www.gushiciku.cn/pl/2hKl/zh-tw
說資料庫最大的瓶頸來自 io

那我 join 五張表不就要查五次
這兩種說法到底哪個是正確的
ps 假設這資料庫是傳統正規化後的表

看更多先前的討論...收起先前的討論...
ckp6250 iT邦好手 1 級 ‧ 2021-07-28 07:28:17 檢舉
測了就知道,
所以,最好的方法是,把實例拿出來,然後提出想要的結果,
跑一遍就知道了,

不然,紙上談兵,沒一個準的。
星空大也有講了,現在使用全SSD的SQL愈來愈普及(我也是一份),IOPS瓶頸反倒不是問題,問題會是你的主機的記憶體夠不夠大來放那些準備JOIN的資料結果,我開64GB了還是會被吃到95%,你說呢?
基本上很多人老愛 SELECT *,如果不這麼做,只撈需要的欄位,需要的時候再去JOIN,基本上單次傳輸量低一點,多次傳輸,對IO 的要求就會大幅降低
尤其是多工作業,單次傳輸量低,每次占用的IO時間也會減短,就算設備IO速度不高,也能滿足多工作業要求,有看過有資料表的資料是逐欄查詢的嘛,為什麼要逐欄,不一次拉完,最簡單的就是你的記憶體跟IO 一次拉完的時間跟負載佔用太多的系統時間,會影響到下一筆工作的時間,個人淺見,聽聽就好
重點是SQL會把SELECT過的表CACHE在記憶體一份,直到資料過期或有新的SELECT把最舊的CACHE擠出去.....系統想藉記憶體來提升重覆查詢速度,但現在硬碟都不慢了,記憶體反倒有點雞肋....
SQL 的效能調教是門學問,剛看到這篇,可以K看看,然後調教一下
https://dba-mike.blogspot.com/2015/10/qna.html
不夠再餵狗 https://www.google.com/search?q=SQL +效能調教
大概得看過一遍,找出目前系統的效能缺失,修正他,再去想到底是語法還是IO
jhit03 iT邦新手 4 級 ‧ 2021-07-29 08:42:45 檢舉
樓主的文章,優化第一點(1. 改變 SQL 執行計劃),就告知優化語句,減少彎路就可以達到 “減少 IO 次數” 和 “降低 CPU 計算” 的目標,表示SQL語法寫得好,一樣可以降低資料庫負擔,是吧??
我自己的習慣是會在SQL整理並撈出必要的資料後才去處理。
因為我覺得資料處理的效能和調整上,SQL Server來處理會比應用層還要來的優。

SQL server的調整方式比較多,光處理查詢與索引的關聯性就可以得到很大的助益,很多如果不在SQL中先優化查詢,你有可能會從SQL server中丟出一大堆沒有用到的資料,這樣反而會拖累效能。而且丟出一大堆沒用的資料,從資料庫到應用層的中間的效能可能都會影響到,有時候要考量的範圍反而會比哪邊處理資料還要廣泛,也更加複雜。

另外一點是,大範圍的資料查詢你還要考慮到table locked的問題,如果應用層同時間很多使用者的話反而會增加整體系統的問題。
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
10

認真來說,這些都是資料庫優化的方式。
正常來說,早期來說,確實IO是首當其衝的問題之一。
但就現階段的硬體來看。使用SSD的話。
IO的讀寫問題就顯得不那麼明顯重要了。
漸漸的,開始有了新的做法及看法了。

JOIN的用法,其實現在新的做法,如ORM的應用。
就是已經走向不用JOIN的方式
其也突顯了JOIN的使用之效能優化的必要性。

但曾經也有人跟我說。那我不分表全部放在同一張表的情況下。是不是比較好?
這就不一定了。
一張表太大,也會去影響到RAM的使用率。
而大多數分表來說,其最大的目的是依需求而取用的目的。大大的降低讀取及使用的容量。

結論:
並不是說,JOIN用多不好,還是IO問題就盡量少讀。
這些並沒有一定的絕對性。
畢竟,量大量小或是分區分配的情況不同。 有適合用子查尋、也有適合用JOIN。
也有適合多並發請求。
這些並沒有一定絕對性說哪種方法比較好及比較不好。
只有適合及不適合你當下的應用架構及寫法。

2
I code so I am
iT邦高手 1 級 ‧ 2021-07-29 09:17:58

個人認為資料庫瓶頸在於大table的join,也在I/O,視使用情境的不同。
例如,兩個幾百萬筆的大table要join, 比對勢必對資料庫產生極大的負擔,解決辦法很多:

  1. 各自撈下來,由Client端PC處理,可幫Server減壓。
  2. 反正規化,把常用的join放在同一個表。
  3. 使用 stored procedure。
  4. 使用 NoSQL 資料庫或Time Series Database。
  5. Partition、Sharding等分散式處理。

相對的,若網站使用者很多,頻繁查詢資料庫,自然造成I/O瓶頸,,解決辦法也很多:

  1. 使用資料庫的Cache。
  2. 將常查詢的資料,例如最新股價,拉出來成為單獨的資料表。
  3. 使用 Redis 或 Memory Database。
0
打雜工
iT邦研究生 1 級 ‧ 2021-07-30 22:55:24

用實際的狀況跑分析最準,不同的狀況,發生的瓶頸也以可能會改變

我要發表回答

立即登入回答