iT邦幫忙

1

不常異動的資料如何加速讀取

  • 分享至 

  • xImage

站上找不到相關資料,不曉得是不是下錯關鍵字

舉例,像是地址區域..台北市中正區...這種資料,這種幾乎萬年不動的資料,如果每次都要去 db 撈,似乎有點浪費時間,萬一有人寫在迴圈 call funtion ,這 funtion 又去撈這種資料,那就更..... =.=

目前是 C# + winform, three tier 的架構, 我的想法是初次執行還是先從 db 取,程式未關前就不再從 db 撈,看是從 memory or local file 讀,不曉得這種做法會不會不妥,有沒有什麼建議的方式,感謝

看更多先前的討論...收起先前的討論...
dragonH iT邦超人 5 級 ‧ 2020-12-17 11:13:33 檢舉
>如果每次都要去 db 撈,似乎有點浪費時間

有聽過 redis 嗎
心累 iT邦新手 5 級 ‧ 2020-12-18 08:28:33 檢舉
寫死本地,定期DB更新,如上線系統在半夜不錯
萬年不動的資料,可以簡單使用 Memory Cache (記憶體快取) 就好,邏輯和文中提到的相同,第一次先從 DB 取,第二次開始從 Cache 取。
放 ssd 啊,萬年不動又要讀取快,就放ssd就好,資料庫建立的時候可以把data file 放到 ssd 上面,異動量大的資料,不建議放ssd,因為rw頻率高,ssd壽命會縮短
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
3
japhenchen
iT邦超人 1 級 ‧ 2020-12-17 12:06:55
最佳解答

把不常變動的資料做成json檔,存在本地,你的程式啟動時檢查檔案建立時間是否超過一個定數(我設8小時),超過的話重新從資料庫重建一份,我在Web主機上定時建立一份全新json檔,WinForm的client端會來下載,零點幾秒的事

至於json跟C#或VB.NET的物件或陣列互相轉化,我用newtonsoft的JsonConvert.SerializeObject及DeSerialize (在nuget可免費下載)

以前的人都用access的mdb檔做本地庫,但遇到重覆執行程式就會跳出共用錯誤,煩都煩死,所以我才會用json來取代mdb,又不用另外掛什麼mdac或ms oledb ,方便又好用

holton iT邦新手 4 級 ‧ 2020-12-17 13:44:37 檢舉

感謝回應

沒想到我目前測式中的想法跟前輩做法差不多,我是一類就存一個 json 檔,重新登入系統就砍掉舊的再抓一次另存,只是偶爾還是會遇到 「...另一個處理序正在使用檔案...所以無法存取該檔案」之類的錯,大概是程式沒寫好

至少,這樣的想法不會太奇怪,哈哈

redis對資料快取而言,略嫌肥大,因為我只是想利用快取加快"類別、選單選項、郵政編號..."這些萬年不變的資料,要是讓這些資料的提取都得向Server或Service索取,就很難避免網路擁塞的問題,對資料庫的負擔也是一個無法估算的開銷,快取本地化就成了必要之惡

至於使用json仍有死鎖的問題,可能是出在於你開檔並無立即關閉吧?我只在程式載入時才載入json檔並進行DeSerialize成object或iEnumerable可序列清單裡,讀完即關,就算要讀json檔,也別用exclusive open,應該可以避免開檔死鎖的狀況

1

一般做法如下

1.redis : 目前大多比較推這招。不過需要了解一下這個技術上的應用。

2.json : 將資料存成json。在做對應處理。不過這不太適合大資料。

3.緩存式 : 在資料在第一次生成就緩存到本地端。可搭配json來處理。這招算是最比較不操效能的方式。可惜的是,不適合用在有安全性的資料上。畢竟資料都會存在本地端應用。

4.本地化處理 : 不太適合網頁的做法。但一般應用可以用資源檔的方式應用。跟第3點的用法大同小異。差別是不需要跟server請求。但缺點是,如有資料變動的話。則需要更新處理。

其它其實也有搭配如orm或是共用資源的方法。這些大多是開發者額外想出的方式。跟緩存的意思有點類同。

基本上地址這一類的東西。如果是搭配3+2的應用。
我目前的做法是db跟json同時並存。

後台編輯處理是編輯db內的資料。編輯完成後,會做生成json檔的動作。
實際前端應用的程式取到的是json的資料。
且json的資料因為地址的資料很大,全放同一個json不可能。我切分區分檔記錄。
反正都是靠生成的,我也不用太擔心維護的問題。

但後台編輯則才是db的資料。

holton iT邦新手 4 級 ‧ 2020-12-17 14:00:52 檢舉

感謝回應

redis 問過我們家 dba ,似乎不建議,而且我一開始的想法也是儘量不動架構的情況下來改

目前就是用存 json 的方式來試,當然,資料一定跟安全性無關的才會這樣做

1
ckp6250
iT邦好手 1 級 ‧ 2020-12-17 16:22:24

  我覺得要先評估這些所謂【幾乎萬年不動的資料】到底有多少筆?對系統效率影響有多大來做決定,以目前電腦系統的效能來說,幾百萬筆根本不算什麼,如果能加速的有限,就不如不要花精神。

  舉例來說,【統編=>公司名稱、地址】可以稱得上幾乎萬年不動,我做了一個資料庫,把全國的統編都納入,每月更新一次,總計三百多萬筆,需要撈資料時,就以統編 inner join 出公司名稱或地址,根本沒耗掉什麼時間(如下圖)。

https://ithelp.ithome.com.tw/upload/images/20201217/20119662XLbvR7AS2S.png

  所以,我認為採新技術之前,先評估一下能提昇多少差異。

holton iT邦新手 4 級 ‧ 2020-12-18 08:19:44 檢舉

感謝回應

你的說法似乎也聽過,說是現今網路夠快、電腦 or server 等級已經夠好,還需要考量提升那一點點的效能嗎

的確,如果需要花太多成本,也許就不適合了,尤其是一個維運很久的系統

0
I code so I am
iT邦高手 1 級 ‧ 2020-12-18 07:52:27

我多年前的作法:

  1. 資料一樣放在資料庫。
  2. 每個不常異動的Table寫一個 trigger(可以是同一個stored procedure),若 Table 有異動,會統一將最新異動時間記錄在另一個Table上,譬如 ChangeDatetime table。
  3. Client端寫一個 TaskTray 程式,每隔一段時間讀取 ChangeDatetime table,如果有異動,就重新從 DB 載入至 memory。
  4. Application 一律從 memory 讀取不常異動的資料。

當時,User及客戶IT部門都非常滿意。

上述流程,現在可以使用 Redis 來實現,只是要考慮大量資料時,如何做 Persistence,及開機時大量資料載入的效能問題,萬一,Redis Server 掛掉,IT 工作不會一起掛掉。

holton iT邦新手 4 級 ‧ 2020-12-18 08:31:26 檢舉

感謝回應

看到不一樣的作法也是一種學習,只是,當初這樣作會不會有 oom 的問題?

不會,使用 Client 端儲存資料,至少可以存 1、2GB 資料。

0
賽門
iT邦超人 1 級 ‧ 2020-12-18 08:54:11

網頁的話, 可以先放到Session或ViewBag裏要用時再轉到DropDownList中, 就可調用了.
我是指ASP.NET C#的技術.

我要發表回答

立即登入回答