在開發中警用會遇到查詢很慢的問題,尤爲是當數據量上去的時候,那麼咱們就要開始優化咱們的程序or前端
數據表mysql
1:通常針對表結構進行優化,採用中間表算法
2:優化sql,使用索引,sql
3:利用MySQL主從作讀寫分離數據庫
四:採用緩存機制,緩存
5:垂直節分,從實際業務上進行拆分,好比電商網站通常都是廣告,你們電,小家電之類的拆開併發
6:水平切分,針對一張表進行節分,這樣保證了不會出現一張表太大狀況,可是要作好路由規則,如今通常都採用的一致性哈希算法進行路由。分佈式
下面挨個分析:函數
1:通常針對表結構進行優化,採用中間表優化
第一條,針對表結構進行優化,再設計表的時候並非按照數據庫三範式,咱們通常採用的是這種的方式設計表,
第一範式:數據表中的每一行都是不可分割的原子列,
好比有一個選課的表 Student_Course(studentId, studentName, collegueId, collegueName, courseId, courseName, grade, credit, courseId1, courseName1, grade1, credit1)
這樣子若是增長了新的課程沒有可擴展性。
爲了知足第一範式,咱們的設計結果不能使用一個courseName而後用,號分割。 沒有可讀性,查詢起來也很麻煩。
只能有重複的行了,Student_Course(studentId, studentName, collegueId, collegueName, courseId, courseName, grade, credit)
這樣就須要用聯合主鍵了studentId和courseId決定了一條記錄
第二範式:實體屬性徹底依賴於主鍵關鍵字。 他要求數據庫表中的實例或行必須被惟一區分,爲實現他的分區,一般爲表加一列,以存儲每一個表的惟一標示,這一列通常都是主鍵列
就是像上面這種狀況使用聯合主鍵的,
(studentId, courseId) -> grade
studentId -> studentName, collegueId, collegueName
courseId -> courseName, credit
會有以下的問題:
數據冗餘: 若是一我的選擇了N門課,就會形成studentName, collegueId, collegueName,courseName, credit這些都重複n次
更新異常,若是修改了credit,那麼須要修改全部記錄的,有可能形成同一個課程學分不一樣
插入異常,若是新開一門課程,若是沒人選修則沒法插入
刪除異常,若是選修完了,那麼課程也一樣要刪除掉。
修改的辦法爲修改成三個表
Student(studentId, studentName, collegueId, collegueName)
Course( courseId1, courseName1, credit1)
Student_Course(studentId, courseId, grade)
第三範式: 非主屬性對候選關鍵字沒有傳遞依賴 一對多
studentId-> collegueId -> collegueName 且 collegueId-> studentId(不是一對一)
Student 這張表有問題, 一樣會帶來2Nf的那些問題。 能夠再單獨分離爲一個類,變爲
Student(studentId, studentName, collegueId)
collegue(collegueId, collegueName)
範式的缺點:範式爲了消除冗餘列,會增長表數據增長了查詢的複雜度,其實能夠適當使用冗餘列來提升查詢速度
優勢:節約空間,會提供更豐富的查詢選項
所以咱們再設計表的時候要容許必定的冗餘列存在。
2:優化sql,使用索引
1):應該避免select * 這樣的操做,由於他是全局檢索的
2):where 和join的字段應該有索引,應當注意的時候,join在主鍵和外鍵數據類型相同的時候,若是值同樣就更好
3):在like的時候,若是第一個字符是通配符,那麼索引將會失去做用
4):使用函數的時候,索引會失去做用
5):少使用!=,由於在這個操做中,索引是失效的
6):索引應當建在update少的字段上,並且重複數據很少的字段上,這樣纔會更高效
7):若是在用order by時候有多個字段,能夠考慮使用複合索引
...還有不少
索引是有mysql的引擎支持的,所以引擎不一樣,索引支持的類型可能就不一樣,以InnoDB來講支持聚簇索引,可是MyISAM只支持全文索引
三:讀寫分離
通常業務量上去了,就會作mysql的主從,讀寫分離,寫操做主庫,讀操做從庫,能夠最大限度的利用如今資源,
關於具體操做有不少,有事基於Mybatis的動態數據源切換的,還有阿里的Cobar和Mycat中間件均可以。
四:緩存機制
如今通常都是使用NoSql數據庫做爲數據庫前端的緩存,通常吧首頁,常常用來查詢的數據放在緩存中,採用消息機制保證緩存的一直性,同時爲了不緩存擊穿,能夠把一些值存爲null
五:垂直切分
垂直切分就是從業務層次進行考慮,把業務拆分爲多個,上面所說經的電商的,廣告,小家電,你們電,日化等分庫存儲,可是這也帶來join的問題,沒法跨庫join,通常是從程序層面去解決,這樣優勢就是減小了庫的併發
六:水平切分
表級別的切分,這樣好處就是不會出現太大的表,表與表之間能夠直接join,缺點就是分片規則很差定,分片帶來事務也很差解決
你會發如今垂直切分和水平切分的時候都會帶倆分佈式一致性的問題,還有不一樣節點join的問題,此外還有讀取排序的問題
所以咱們最好就是採用靠譜的中間件進行,由於那樣對開發人員來講是無感受的,基於mysql的協議,咱們認爲就是讀一個庫,由中間件進行復雜的處理,還有就是能不分的就不分,能不join的就不join