謝謹輝
實踐出真知。根據成本順序依次是:
第一:加索引優化sql。儘量避免全盤掃描,另單表索引也不是越多越好。
第二:加緩存。使用redis,memcached,但注意緩存同步更新、設置失效等問題。
第三:主從複製,讀寫分離。適合讀多寫少的場景,同步會有延遲。
第四:垂直拆分。可以選用適當的中間件Mycat等
第五:水平切分。選擇合理的sharding key,改動表結構,將大數據字段拆分出去,對經常查詢的字段做一定的冗餘,同時做好數據同步。
當然還有優化數據庫連接配置,根據業務選用不同的數據庫引擎等等。
我是一名架構師,歡迎關注,給技術加點料
Java全棧技術
我的天啦,一個表九千萬也是了不得了!
我上家公司明確規定,一張表不能超過5000萬,因為查詢效率會有更大的降低!
無論如何,看下如何優化數據查詢吧!
①,單庫單表:
1,加索引,一個好的索引能用空間換取查詢時間的大為降低!
2,使用存儲過程:減少sql編譯的時間!
3,優化sql:包括聯合查詢的指向,where,order語句使用索引字段,減少使用多表聯合查詢,不要使用select *等等!
4,參數配置:擴大內存,調節線程池參數等等!
5,開啟緩存:開啟二級緩存,三級緩存,提升查詢效率!
②,單庫多表:
使用水平拆分(比如按月份),將表分為12張表,然後在代碼端按照月份訪問相應月份的表!
使用垂直拆分:很多字段只是作為保存記錄用,(像一些約定,備註啥的字段往往很大),可以將查詢中常常用到的字段放在常用的一張表中做查詢,另一些字段放另一張表中存儲,通過某個唯一索引字段聯繫起來,可以保證查詢效率大為提升(因為磁盤IO減少)!
③,多庫多表:
①,主從讀寫分離:表中數據雖然還是一致,但是由於多個從庫讀,主庫寫數據,大大減少共享鎖的性能開銷!
②,分庫分表:指定一個字段作為,分庫字段,利用hash值或者其它策略,分佈在不同的庫裡面,在按照相應分佈策略(比如上面的水平拆分或者垂直拆分),分散到不同的表裡!
比如我們現在的數據庫設計為8庫1024表,你的將近一億的數據在我們的單張表裡面只有不到10W!
雖然理論上,一張表的大小不做任何限制,但是基於查詢效率,索引性能等,不宜超出5000萬數據!
關於多線程,分佈式,微服務,數據庫,緩存的更多幹貨,會繼續分享,敬請關注。。
謝逅架構
作為一個多年的WEB後端程序員,經常與各種數據庫打交道,下面分享一些自己的處理方式給你。
對於數據量這麼大的數據,MySQL提供了以下優化方案:
1.常規方式索引,這裡需要注意的是,索引也是一種文件,如果你的服務器或者數據庫內存非常小,一次無法將所有的索引文件載入,這個時候索引文件因為要反覆在磁盤和內存之間進行切換,這樣效果肯定非常不明顯,導致查詢也變慢,所以這種情況可以適當增加內存,以滿足索引文件一次載入到內存進行檢索查詢。
2.表分區保存,對於這麼大的數據,可以根據具體的需求進行表分區保存,在進行表分區保存的時候,需要注意,一定要根據具體的需求進行分區,這和建立索引是一樣的道理。
3.用程序實現分表保存,比如在保存和查詢數據的時候,生成主鍵時,可以用某種規則將其保存在90個表左右,這樣就變成了90個100萬數據的表,查詢肯定會提升,不過對於分表保存,目前MySQL數據庫對於INNODB存儲引擎沒有提供太多的支持,所以這一切必須由我們自己寫程序來實現。
如果你還有什麼問題,可以在評論中留言。
互聯網知天下
我不清楚答題的大部分人是否有真正實踐過,特別是用mysql實踐過。大部分說是加索引、調整參數不是說不正確,有效果,但是不能很好的解決問題。說說個人想法:
部分答主的方案的確不敢苟同,糾正如下:
1、select count(*) 和 select count(主鍵) 在現階段的mysql 沒有太大區別,新版mysql這個對性能影響可以忽略。
2、強烈反對使用存儲過程,後面介紹了使用分表分庫的方案,就更不要用存儲過程了。
3、單錶行數和表數量,需要找到平衡點。表太多,性能也會下降。
我的回答:
1、單表9000w數據,mysql存儲不了,想辦法分表分庫。500w數據的時候,你就該有這個想法了。只加索引解決不了問題,9000w的單表數據,很難平衡查找和插入性能,索引稍微多了插入性能也很低。
2、不要再說select count了,放棄彙總查詢的想法,根本查不了。
3、數據最終以mysql作為主要存儲,考慮最終查詢的數據源放在非關係的數據存儲上,mongo,es都可以考慮下。
4、業務場景都是需要實時查詢9000w數據嗎?非實時數據,可以考慮hadoop系大數據方案。
5、最後說下,mysql 和oracle,sql server不一樣,不一樣。
ITmifen
是一張表九千萬了嗎?
建議:
第一、表讀居多還是寫?讀的話數據庫引擎用myisam ,寫的話InnoDB 而不是MyISAM,因為MyISAM有太多鎖。
第二、升級到MySQL 5.5 ,確保使用buffering功能。
第三,索引確保使用正確,且都在內存中,移除沒有必要的索引。
第四、寫場景多嗎? 設置innodb_buffer_pool_size足夠大來確保更快的寫操作。
第五、按業務id取模,分表。
最後,花錢加機器內存和用ssd磁盤吧。
小鳥攻城獅
首先應該看你們是什麼業務,針對業務類型的不同可以採取不同的優化方式。
1.如果是線上環境,對外提供服務,這個表確實是很大了,無論索引設計的多麼合理,進行查詢和插入的時候都會耗時較長,性能低下。特別是遇到連表查詢的時候,會更慢。這個時候可以考慮進行分表或者分區表。
1.1分表:是將一個大表按照一定的規則分解成多張具有獨立存儲空間的實體表,我們可以稱為子表。app讀寫的時候需要先根據事先定義好的規則得到對應的子表名。
1.2分區表:和分表相似,都是按照規則分解表。不同在於分表將大表分解為若干個獨立的實體表,而分區是將數據分段劃分在多個位置存放,可以是同一塊磁盤也可以在不同的機器。分區後,表面上還是一張表,但數據散列到多個位置了。app讀寫的時候操作的還是大表名字,這種方式對程序來說是透明的,無需更改程序。不過要注意sql查詢的時候需要加上可以定位到某個分區表的條件,否則會是整個大表掃描,性能比未分區前更慢。
分區的類型有:
RANGE分區:基於屬於一個給定連續區間的列值,把多行分配給分區。
LIST分區:類似於按RANGE分區,區別在於LIST分區是基於列值匹配一個離散值集合中的某個值來進行選擇。
HASH分區:基於用戶定義的表達式的返回值來進行選擇的分區,該表達式使用將要插入到表中的這些行的列值進行計算。這個函數可以包含MySQL 中有效的、產生非負整數值的任何表達式。
KEY分區:類似於按HASH分區,區別在於KEY分區只支持計算一列或多列,且MySQL服務器提供其自身的哈希函數。必須有一列或多列包含整數值。
除了分表和分區表外,還可以採取緩存,redis或者mamecache,降低mysql數據庫的壓力。
2.如果是統計業務,則可以採取別的數據庫存儲數據,像是列數據庫,mariadb columnstore ,計算能力比myslq強大很多。
luckylinda68
最簡單的方法就是優化查詢,第一點,可以建立索引,因為索引可以很大程度優化查詢。第二點,可以配置緩存還可以用slow_query_log進行分析,這樣很大提升查詢的。第三點,建立分庫分表,因為分庫分表是查詢的殺手鐧。第四點,優化sql語句,比如子查詢的優化等。第五點,就是在連表查詢是要使用Join表的時候使用相當類型的例,並將其為索引。
網絡達人之心
首先應排除存儲過程裡的代碼和表設計本身存在的效率問題。然後明確使用場景的特點,比如讀寫比例、冷熱數據訪問比例等,然後再針對性能瓶頸來制訂具體優化方案。大多數情況下,可以考慮分庫分表、冷熱分離和讀寫分離,以及增加分佈式緩存降低數據庫負載等。
晴月浩新雪
上Mongo吧,方便分片,自動負載管理路由。
一抹斜陽70814
分表加上memorycache,其實數據表規模大不可怕,把搜索的關鍵字索引扔到內存庫裡,用外鍵ID做關聯效率會很高。如果數據複雜可以結合nosql做緩存(redis可定時釋放)