導航:首頁 > 數據分析 > 百萬級數據如何遍歷

百萬級數據如何遍歷

發布時間:2025-01-17 05:41:44

⑴ 設計大型資料庫需要注意哪些地方


一個面試問題,關於資料庫的設計。 面試開始那位仁兄直接的說了他所面臨的問題,公司資料庫數據到達百萬級別,以後可能會到達千萬,需要一個好的設計人員對資料庫進行優化設計,這里指的是不光設計符合功能需求,更加要符合性能需求,就是說資料庫設計上面需





一個面試問題,關於資料庫的設計。


面試開始那位仁兄直接的說了他所面臨的問題,公司資料庫數據到達百萬級別,以後可能會到達千萬,需要一個好的設計人員對資料庫進行優化設計,這里指的是不光設計符合功能需求,更加要符合性能需求,就是說資料庫設計上面需要兼顧到效率。


他給我出了一道題目, 一個信息表,一個類別表。類別表中的類別成樹形結構的,這個樹可能會非常深,就是說類別會很多。信息表中有所有類別的信息。現在需要設計下類別表和信息表,使得信息表和類別表在查詢的效率能夠承受千萬級別的數據。


我用比較正常的思維去設計,類別表中有id,name,parentid。這時候他說如果以這種方式設計那在查詢的時候不斷的用嵌套的方式查詢效率不行,他讓我想下,我說可以將類別表分為幾個小表和信息表聯結查詢,他說這個方法不行。他就直接給我講了他的方法,但是他說這個方法百萬級可以,但是千萬級的不行,他的方法也簡單,設第一個大類為1,第一個大類下面的一個類別為2,那麼在類別表中存儲


id name category_id
1 第一大類下的一個小類 Ƈ,2'

那麼在查詢的時候 select * from category where category_id like Ƈ%'


只要like後面不要寫'%1%'。 1的前面不要寫%,在效率上面還是能夠承受的,這個和索引類似。


他也指出雖然這種方法提高了一定效率但是每次有一個新類別加入時候總要再次遍歷整個樹形類別,在適合的位置插入,這樣子的方式給維護類別表格帶來一定麻煩。


一個好的資料庫產品不等於就有一個好的應用系統,如果不能設計一個合理的資料庫模型,不僅會增加客戶端和伺服器段程序的編程和維護的難度,而且將會影響系統實際運行的性能。一般來講,在一個MIS系統分析、設計、測試和試運行階段,因為數據量較小,設計人員和測試人員往往只注意到功能的實現,而很難注意到性能的薄弱之處,等到系統投入實際運行一段時間後,才發現系統的性能在降低,這時再來考慮提高系統性能則要花費更多的人力物力,而整個系統也不可避免的形成了一個打補丁工程。筆者依據多年來設計和使用資料庫的經驗,提出以下一些設計准則,供同仁們參考。


命名的規范

不同的資料庫產品對對象的命名有不同的要求,因此,資料庫中的各種對象的命名、後台程序的代碼編寫應採用大小寫敏感的形式,各種對象命名長度不要超過30個字元,這樣便於應用系統適應不同的資料庫。


游標(Cursor)的慎用

游標提供了對特定集合中逐行掃描的手段,一般使用游標逐行遍歷數據,根據取出的數據不同條件進行不同的操作。尤其對多表和大表定義的游標(大的數據集合)循環很容易使程序進入一個漫長的等特甚至死機,筆者對某市《住房公積金管理系統》進行日終帳戶滾積數計息處理時,對一個10萬個帳戶的游標處理導致程序進入了一個無限期的等特(後經測算需48個小時才能完成)(硬體環境:Alpha/4000 128Mram,Sco Unix ,Sybase 11.0),後根據不同的條件改成用不同的UPDATE語句得以在二十分鍾之內完成。示例如下:


Declare Mycursor cursor for select count_no from COUNT
Open Mycursor
Fetch Mycursor into @vcount_no
While (@@sqlstatus=0)
Begin
If @vcount_no=』』 條件1
操作1
If @vcount_no=』』 條件2
操作2
??
Fetch Mycursor into @vcount_no
End
??
??
改為
Update COUNT set 操作1 for 條件1
Update COUNT set 操作2 for 條件2
??
??

在有些場合,有時也非得使用游標,此時也可考慮將符合條件的數據行轉入臨時表中,再對臨時表定義游標進行操作,可時性能得到明顯提高。筆者在某地市〈電信收費系統〉資料庫後台程序設計中,對一個表(3萬行中符合條件的30多行數據)進行游標操作(硬體環境:PC伺服器,PII266 64Mram ,NT4.0 Ms Sqlserver 6.5)。 示例如下:


Create #tmp /* 定義臨時表 */
(欄位1
欄位2
??
)
Insert into #tmp select * from TOTAL where
條件 /* TOTAL中3萬行 符合條件只有幾十行 */
Declare Mycursor cursor for select * from #tmp
/*對臨時表定義游標*/
??

索引(Index)的使用原則

創建索引一般有以下兩個目的:維護被索引列的唯一性和提供快速訪問表中數據的策略。大型資料庫有兩種索引即簇索引和非簇索引,一個沒有簇索引的表是按堆結構存儲數據,所有的數據均添加在表的尾部,而建立了簇索引的表,其數據在物理上會按照簇索引鍵的順序存儲,一個表只允許有一個簇索引,因此,根據B樹結構,可以理解添加任何一種索引均能提高按索引列查詢的速度,但會降低插入、更新、刪除操作的性能,尤其是當填充因子(Fill Factor)較大時。所以對索引較多的表進行頻繁的插入、更新、刪除操作,建表和索引時應設置較小的填充因子,以便在各數據頁中留下較多的自由空間,減少頁分割及重新組織的工作。


數據的一致性和完整性

為了保證資料庫的一致性和完整性,設計人員往往會設計過多的表間關聯(Relation),盡可能的降低數據的冗餘。表間關聯是一種強制性措施,建立後,對父表(Parent Table)和子表(Child Table)的插入、更新、刪除操作均要佔用系統的開銷,另外,最好不要用Identify 屬性欄位作為主鍵與子表關聯。如果數據冗餘低,數據的完整性容易得到保證,但增加了表間連接查詢的操作,為了提高系統的響應時間,合理的數據冗餘也是必要的。使用規則(Rule)和約束(Check)來防止系統操作人員誤輸入造成數據的錯誤是設計人員的另一種常用手段,但是,不必要的規則和約束也會佔用系統的不必要開銷,需要注意的是,約束對數據的有效性驗證要比規則快。所有這些,設計人員在設計階段應根據系統操作的類型、頻度加以均衡考慮。


事務的陷阱

事務是在一次性完成的一組操作。雖然這些操作是單個的操作,SQL Server能夠保證這組操作要麼全部都完成,要麼一點都不做。正是大型資料庫的這一特性,使得數據的完整性得到了極大的保證。


眾所周知,SQL Server為每個獨立的SQL語句都提供了隱含的事務控制,使得每個DML的數據操作得以完整提交或回滾,但是SQL Server還提供了顯式事務控制語句:


BEGIN TRANSACTION 開始一個事務
COMMIT TRANSACTION 提交一個事務
ROLLBACK TRANSACTION 回滾一個事務

事務可以嵌套,可以通過全局變數@@trancount檢索到連接的事務處理嵌套層次。需要加以特別注意並且極容易使編程人員犯錯誤的是,每個顯示或隱含的事物開始都使得該變數加1,每個事務的提交使該變數減1,每個事務的回滾都會使得該變數置0,而只有當該變數為0時的事務提交(最後一個提交語句時),這時才把物理數據寫入磁碟。


資料庫性能調整

在計算機硬體配置和網路設計確定的情況下,影響到應用系統性能的因素不外乎為資料庫性能和客戶端程序設計。而大多數資料庫設計員採用兩步法進行資料庫設計:首先進行邏輯設計,而後進行物理設計。資料庫邏輯設計去除了所有冗餘數據,提高了數據吞吐速度,保證了數據的完整性,清楚地表達數據元素之間的關系。而對於多表之間的關聯查詢(尤其是大數據表)時,其性能將會降低,同時也提高了客 戶端程序的編程難度,因此,物理設計需折衷考慮,根據業務規則,確定對關聯表的數據量大小、數據項的訪問頻度,對此類數據表頻繁的關聯查詢應適當提高數據冗餘設計。


數據類型的選擇

數據類型的合理選擇對於資料庫的性能和操作具有很大的影響,有關這方面的書籍也有不少的闡述,這里主要介紹幾點經驗。


Identify欄位不要作為表的主鍵與其它表關聯,這將會影響到該表的數據遷移。


Text 和Image欄位屬指針型數據,主要用來存放二進制大型對象(BLOB)。這類數據的操作相比其它數據類型較慢,因此要避開使用。


日期型欄位的優點是有眾多的日期函數支持,因此,在日期的大小比較、加減操作上非常簡單。但是,在按照日期作為條件的查詢操作也要用函數,相比其它數據類型速度上就慢許多,因為用函數作為查詢的條件時,伺服器無法用先進的性能策略來優化查詢而只能進行表掃描遍歷每行。


例如:要從DATA_TAB1中(其中有一個名為DATE的日期欄位)查詢1998年的所有記錄。


Select * from DATA_TAB1 where datepart(yy,DATE)=1998

⑵ EasyExcel快速導出 100W 數據

導出是後台管理系統中的常見功能。當數據量巨大時,內存溢出和頁面卡頓問題便成為挑戰。曾嘗試封裝一個導出工具,採用分批查詢數據的方法來防止內存溢出,以及使用SXSSFWorkbook緩存數據至文件,以解決下載大型EXCEL文件時頁面卡死的問題。然而,這些方法存在封裝不夠友好、POI操作內存佔用過大、空循環和整除數據不完整以及內存溢出隱患等問題。

偶然間發現了阿里開源的EasyExcel框架,發現其內存佔用量控制在KB級別,並且完全避免了內存溢出問題(具體實現細節待進一步研究)。其速度極快,大約100萬條記錄,包含多個欄位的情況下,僅需70秒即可完成下載。因此,決定棄用原有封裝,轉而研究EasyExcel。盡管自己的封裝具有一定技術含量,包括外觀模式、模板方法模式、委託和組合思想,但EasyExcel提供了更為高效和便捷的解決方案。關注Java技術棧,搜索設計模式,可以獲取Java設計模式實戰教程

EasyExcel的GitHub地址為:github.com/alibaba/easy...

案例

根據不同數據量,EasyExcel提供了以下策略:
- 數據量較小(20萬以內):一次查詢導出一個SHEET;
- 數據量適中(100萬以內):分批查詢導出一個SHEET;
- 數據量巨大(幾百萬條記錄):分批查詢導出多個SHEET。
在生產環境中,對於常量類的編寫應確保數據整除以簡化邏輯。數據量較小的場景下,一次查詢即可完成導出;適中的數據量下,分批查詢一個SHEET;而大量數據時,則需採用多個SHEET分批查詢。

總結

進行了100萬條記錄、18個欄位的數據導出測試,結果顯示耗時約70秒。具體使用情況還需考慮SQL性能。在進行分頁時,推薦採用單表查詢並一次性獲取所需外鍵對應冗餘欄位,使用@MapKey註解進行映射,之後遍歷時從map中獲取對應名稱。秉持少發查詢SQL的原則,以加速導出過程。額外提示:數據量過大時,應避免使用傳統分頁策略,轉而採用where id> #{lastMaxId} order by id limit 100的方法解決分頁效率問題。

⑶ 對比一些MQTT的代理(broker)

broker的主要職責是接受發布者發布的所有消息,並將其過濾後分發給不同的消息訂閱者。
如今有很多的broker,下面就是一張關於各種broker對比的圖片:

目前我用過的有mosquitto和emqttd(2.0版本後改叫EMQ),因為目前的需求是希望做每秒10萬以上的數據接入,所以需要考慮建立集群。但是在使用mosquitto的過程中發現他不支持集群,所以就放棄了,轉投emqttd。
在使用mosquitto過程中發現了一些問題:
在使用mosquitto時,如果想使用集群的話,可能會需要進行二次開發。目前只支持橋接。並且他在遍歷時的效率非常低,使得他無法支持大量的客戶端或者操作過於頻繁的操作(比如十萬或百萬級別的客戶端同時發送數據)
emqttd有以下優點:

EMQ 2.0 (Erlang/Enterprise/Elastic MQTT Broker) 是基於 Erlang/OTP 語言平台開發,支持大規模連接和分布式集群,發布訂閱模式的開源 MQTT 消息伺服器。(抄自 EMQ官方文檔 )

⑷ mysql 千萬級別的 in 查詢優化

這個主鍵ID其實已經是有建立了索引的了,而在IN查詢當中並沒有用到而已,其實你可以試試IN里的id少些時,是會用到索引的,但當IN里的id占據全表的大部分數據量時,mysql採用的時全表掃描。在這個時候可以考慮:1.split返回臨時表進行表連接,2.使用緩存遍歷

閱讀全文

與百萬級數據如何遍歷相關的資料

熱點內容
推廣安卓app哪些比較簡單 瀏覽:621
命令行顯示文件內容 瀏覽:436
如何分割文件 瀏覽:39
生成py文件到指定目錄 瀏覽:822
linux讀取隨機數文件 瀏覽:903
文件區域網共享 瀏覽:412
交管app什麼時候更新免檢 瀏覽:463
不想iphone和ipad同步 瀏覽:98
壓縮文件質量怎麼樣 瀏覽:337
通達信標記存在哪些文件夾 瀏覽:647
美國蘋果商店ipad 瀏覽:961
iphone備忘錄提示音 瀏覽:801
蘋果5s電信網路設置 瀏覽:31
win10系統中文版嗎 瀏覽:971
公司采購一般公布在哪些網站 瀏覽:70
如何連接車上的無線網路 瀏覽:170
mate7升級emui31 瀏覽:714
tomcat7forlinux下載 瀏覽:437
在根里查找文件linux 瀏覽:819
飢荒安卓人物mod 瀏覽:91

友情鏈接