主頁 > 後端開發 > 資料庫優化

資料庫優化

2020-09-16 15:53:26 後端開發

資料庫優化
為什么要優化
系統的吞吐量瓶頸往往出現在資料庫的訪問速度上
隨著應用程式的運行,資料庫的中的資料會越來越多,處理時間會相應變慢
資料是存放在磁盤上的,讀寫速度無法和記憶體相比
優化原則:減少系統瓶頸,減少資源占用,增加系統的反應速度。

資料庫結構優化
一個好的資料庫設計方案對于資料庫的性能往往會起到事半功倍的效果。

需要考慮資料冗余、查詢和更新的速度、欄位的資料型別是否合理等多方面的內容。

將欄位很多的表分解成多個表

對于欄位較多的表,如果有些欄位的使用頻率很低,可以將這些欄位分離出來形成新表。

因為當一個表的資料量很大時,會由于使用頻率低的欄位的存在而變慢。

增加中間表

對于需要經常聯合查詢的表,可以建立中間表以提高查詢效率。

通過建立中間表,將需要通過聯合查詢的資料插入到中間表中,然后將原來的聯合查詢改為對中間表的查詢。

增加冗余欄位

設計資料表時應盡量遵循范式理論的規約,盡可能的減少冗余欄位,讓資料庫設計看起來精致、優雅。但是,合理的加入冗余欄位可以提高查詢速度。

表的規范化程度越高,表和表之間的關系越多,需要連接查詢的情況也就越多,性能也就越差。

注意:

冗余欄位的值在一個表中修改了,就要想辦法在其他表中更新,否則就會導致資料不一致的問題。

MySQL資料庫cpu飆升到500%的話他怎么處理?
當 cpu 飆升到 500%時,先用作業系統命令 top 命令觀察是不是 mysqld 占用導致的,如果不是,找出占用高的行程,并進行相關處理。

如果是 mysqld 造成的, show processlist,看看里面跑的 session 情況,是不是有消耗資源的 sql 在運行。找出消耗高的 sql,看看執行計劃是否準確, index 是否缺失,或者實在是資料量太大造成。

一般來說,肯定要 kill 掉這些執行緒(同時觀察 cpu 使用率是否下降),等進行相應的調整(比如說加索引、改 sql、改記憶體引數)之后,再重新跑這些 SQL。

也有可能是每個 sql 消耗資源并不多,但是突然之間,有大量的 session 連進來導致 cpu 飆升,這種情況就需要跟應用一起來分析為何連接數會激增,再做出相應的調整,比如說限制連接數等

大表怎么優化?某個表有近千萬資料,CRUD比較慢,如何優化?分庫分表了是怎么做的?分表分庫了有什么問題?有用到中間件么?他們的原理知道么?
當MySQL單表記錄數過大時,資料庫的CRUD性能會明顯下降,一些常見的優化措施如下:

限定資料的范圍: 務必禁止不帶任何限制資料范圍條件的查詢陳述句。比如:我們當用戶在查詢訂單歷史的時候,我們可以控制在一個月的范圍內。;
讀/寫分離: 經典的資料庫拆分方案,主庫負責寫,從庫負責讀;
快取: 使用MySQL的快取,另外對重量級、更新少的資料可以考慮使用應用級別的快取;
還有就是通過分庫分表的方式進行優化,主要有垂直分表和水平分表

垂直磁區:

根據資料庫里面資料表的相關性進行拆分。 例如,用戶表中既有用戶的登錄資訊又有用戶的基本資訊,可以將用戶表拆分成兩個單獨的表,甚至放到單獨的庫做分庫。

簡單來說垂直拆分是指資料表列的拆分,把一張列比較多的表拆分為多張表。 如下圖所示,這樣來說大家應該就更容易理解了。

img

垂直拆分的優點: 可以使得行資料變小,在查詢時減少讀取的Block數,減少I/O次數。此外,垂直磁區可以簡化表的結構,易于維護。

垂直拆分的缺點: 主鍵會出現冗余,需要管理冗余列,并會引起Join操作,可以通過在應用層進行Join來解決。此外,垂直磁區會讓事務變得更加復雜;

垂直分表
把主鍵和一些列放在一個表,然后把主鍵和另外的列放在另一個表中

img

適用場景
1、如果一個表中某些列常用,另外一些列不常用
2、可以使資料行變小,一個資料頁能存盤更多資料,查詢時減少I/O次數
缺點
有些分表的策略基于應用層的邏輯演算法,一旦邏輯演算法改變,整個分表邏輯都會改變,擴展性較差
對于應用層來說,邏輯演算法增加開發成本
管理冗余列,查詢所有資料需要join操作
水平磁區:

保持資料表結構不變,通過某種策略存盤資料分片。這樣每一片資料分散到不同的表或者庫中,達到了分布式的目的。 水平拆分可以支撐非常大的資料量。

水平拆分是指資料表行的拆分,表的行數超過200萬行時,就會變慢,這時可以把一張的表的資料拆成多張表來存放。舉個例子:我們可以將用戶資訊表拆分成多個用戶資訊表,這樣就可以避免單一表資料量過大對性能造成影響。

資料庫水平拆分

水品拆分可以支持非常大的資料量。需要注意的一點是:分表僅僅是解決了單一表資料過大的問題,但由于表的資料還是在同一臺機器上,其實對于提升MySQL并發能力沒有什么意義,所以 水平拆分最好分庫 。

水平拆分能夠 支持非常大的資料量存盤,應用端改造也少,但 分片事務難以解決 ,跨界點Join性能較差,邏輯復雜。

《Java工程師修煉之道》的作者推薦 盡量不要對資料進行分片,因為拆分會帶來邏輯、部署、運維的各種復雜度 ,一般的資料表在優化得當的情況下支撐千萬以下的資料量是沒有太大問題的。如果實在要分片,盡量選擇客戶端分片架構,這樣可以減少一次和中間件的網路I/O。

水平分表:
表很大,分割后可以降低在查詢時需要讀的資料和索引的頁數,同時也降低了索引的層數,提高查詢次數

img

適用場景
1、表中的資料本身就有獨立性,例如表中分表記錄各個地區的資料或者不同時期的資料,特別是有些資料常用,有些不常用。
2、需要把資料存放在多個介質上。
水平切分的缺點
1、給應用增加復雜度,通常查詢時需要多個表名,查詢所有資料都需UNION操作
2、在許多資料庫應用中,這種復雜度會超過它帶來的優點,查詢時會增加讀一個索引層的磁盤次數
下面補充一下資料庫分片的兩種常見方案:

客戶端代理: 分片邏輯在應用端,封裝在jar包中,通過修改或者封裝JDBC層來實作。 當當網的 Sharding-JDBC 、阿里的TDDL是兩種比較常用的實作。
中間件代理: 在應用和資料中間加了一個代理層。分片邏輯統一維護在中間件服務中。 我們現在談的 Mycat 、360的Atlas、網易的DDB等等都是這種架構的實作。
分庫分表后面臨的問題

事務支持 分庫分表后,就成了分布式事務了。如果依賴資料庫本身的分布式事務管理功能去執行事務,將付出高昂的性能代價; 如果由應用程式去協助控制,形成程式邏輯上的事務,又會造成編程方面的負擔。

跨庫join

只要是進行切分,跨節點Join的問題是不可避免的。但是良好的設計和切分卻可以減少此類情況的發生。解決這一問題的普遍做法是分兩次查詢實作。在第一次查詢的結果集中找出關聯資料的id,根據這些id發起第二次請求得到關聯資料。 分庫分表方案產品

跨節點的count,order by,group by以及聚合函式問題 這些是一類問題,因為它們都需要基于全部資料集合進行計算。多數的代理都不會自動處理合并作業。解決方案:與解決跨節點join問題的類似,分別在各個節點上得到結果后在應用程式端進行合并。和join不同的是每個結點的查詢可以并行執行,因此很多時候它的速度要比單一大表快很多。但如果結果集很大,對應用程式記憶體的消耗是一個問題。

資料遷移,容量規劃,擴容等問題 來自淘寶綜合業務平臺團隊,它利用對2的倍數取余具有向前兼容的特性(如對4取余得1的數對2取余也是1)來分配資料,避免了行級別的資料遷移,但是依然需要進行表級別的遷移,同時對擴容規模和分表數量都有限制。總得來說,這些方案都不是十分的理想,多多少少都存在一些缺點,這也從一個側面反映出了Sharding擴容的難度。

ID問題

一旦資料庫被切分到多個物理結點上,我們將不能再依賴資料庫自身的主鍵生成機制。一方面,某個磁區資料庫自生成的ID無法保證在全域上是唯一的;另一方面,應用程式在插入資料之前需要先獲得ID,以便進行SQL路由. 一些常見的主鍵生成策略

UUID 使用UUID作主鍵是最簡單的方案,但是缺點也是非常明顯的。由于UUID非常的長,除占用大量存盤空間外,最主要的問題是在索引上,在建立索引和基于索引進行查詢時都存在性能問題。 Twitter的分布式自增ID演算法Snowflake 在分布式系統中,需要生成全域UID的場合還是比較多的,twitter的snowflake解決了這種需求,實作也還是很簡單的,除去配置資訊,核心代碼就是毫秒級時間41位 機器ID 10位 毫秒內序列12位。

跨分片的排序分頁

般來講,分頁時需要按照指定欄位進行排序。當排序欄位就是分片欄位的時候,我們通過分片規則可以比較容易定位到指定的分片,而當排序欄位非分片欄位的時候,情況就會變得比較復雜了。為了最終結果的準確性,我們需要在不同的分片節點中將資料進行排序并回傳,并將不同分片回傳的結果集進行匯總和再次排序,最后再回傳給用戶。如下圖所示:

在這里插入圖片描述

uj5u.com熱心網友回復:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/58267.html

標籤:Java EE

上一篇:springboot結合dubbo,消費端啟動的問題,詳情見下圖

下一篇:求救啊兄弟萌

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more