1. 程式人生 > 其它 >資料庫的優化包括哪些方面

資料庫的優化包括哪些方面

一、什麼是資料的優化

資料庫的優化是一個綜合型的技術,並不是通過某一種方式讓資料庫效率提高很多, 而使通過多方便的提高,從而使資料提高很多
  主要包括
      1. 表的設計合理化
      2. SQL語句的優化
      3. 給表要新增合適的索引 普通索引、主鍵所以,唯一索引 unique、全文索引
      4. 分表技術(水平分割、垂直分割)
      5. 定時清除垃圾資料、定時進行碎片整理
      6. 多用儲存過程,和觸發器
      7. 對mysql的配置進行優化[配置最大併發數my.ini,調整快取大小]
      8. 讀寫分離
      9. myql伺服器硬體是否要升級

表的設計合理化

   三正規化:
           第一正規化、
                  確保每列的原子性、所有的(不可再分)
                  注意:地址這個欄位,如果不分類彙總,不排序,僅僅是起一個字串的作用,這是我們不拆分(反三正規化)
           第二正規化、
                  非鍵欄位必須依賴與鍵欄位(一個表做一件事情)        
           第三正規化、
                 消除傳遞依賴(如果一個欄位可以推到出到另外一個欄位)
                 
   反三正規化:
       正規化越高,資料的冗餘就越少、但是有的時候效率就越底下,為了提高執行效率,可以適當
       的適當的讓資料的冗餘。
           
   資料庫的效能比規範化更重要        

SQL語句的優化

定位慢查詢

 增、刪、改、查

一、MySql資料庫一個關於狀態的查詢

          show status指令  查詢mysql的執行狀態
          show status like ‘com_insert’ 執行了多少次插入
          show status like ‘com_update’ 執行了多少次更新                         
          show status like ‘com_delete’ 執行了多少次刪除    
          show status like ‘com_select’ 執行了多少次刪除 
          show[session | global ] status like com_select’
          show status like ''uptime' 顯示MySql資料庫啟動多長時間,如果時間很長了,
          資料庫表的儲存引擎是myisan的,這時候就要主要整理碎片。

二、顯示慢查詢

      show  variables like 'long_query_time'
      set long_query_time = 0.5
      show status like 'slow_queries'
      定位慢查詢(開啟慢查詢的日誌)
      一旦開啟慢查詢日誌後,日誌檔案的位置,在my.ini檔案去查詢datadir
      在預設情況下不會開啟慢查詢,如何開啟慢查詢呢
             第一步: 關閉當前的MySql的服務
             第二步: 啟動 mysqld --safe -mode --slow-query-log 
                            關閉 mysqladmin  -uroot -p123456 shut down 

優化問題

    通過explain語句可以分析,mysql如何執行的sql語句

二、資料庫的索引

一、建立適當的索引

    高資料庫效能,索引是最物美價廉的東西了,不用加記憶體,不用改變呼叫sql,只要執行正確的create index 查詢速度就可能提高百倍千倍

二、新增索引

 主鍵索引
        當一張表中某個列設為主鍵的時候,則該列就是主鍵索引
        create table aa(id int unsigned primary key auto_increment,
        name varchar(32) )
         這是id列是主鍵例
 
        第一種 : 查詢索引 desc  表名  不能顯示索引的名字
        第二種 : 查詢索引的show index from 表名
        第三種 : 查詢索引的show keys from 表名、
        
        如果你建立不表的時,沒有指定主鍵索引,也可以在建立表後,在新增指令
        
        alter table 表名  add primary key(列名);
        
        emp.frm      表的結構
        emp.MYD    表的資料
        emp.MYI      表的索引
  普通索引    
       普通索引的建立,是先建立表,然後新增索引
       create index  索引的名字 on 表名(列)
       
  唯一索引    
      當變的某列指定為unique約束時,這列就是一個唯一索引  
      create table ddd(
         id int  primary key not null,
         name varchar(100) unique
      )
 全文索引
     全文索引、主要是針對檔案、文字的檢索,全段索引對Myisam
     錯誤的用法
       select * from articles  where body like '%mysql%'
     
     正確的用法是
     select * from articles where match(title,body) aginst('database')
     
     說明
         1.在mysql中fulltext索引指標對myisam生效
         2.mysql自己提高的fulltest針對英文生效->sphinx(coreseek) 技術處理中文
         3.使用方法是match(欄位名) against(‘關鍵字’)
         4.全文索引一個叫停止詞
       
 刪除索引
 
       alter table 表名  drop index 索引名
      
      如果刪除主鍵索引
        alter table 表名 drop primary key 
        
      修改索引
         先刪除,在重新建立

為什麼建立索引後速度會變快呢 BTree

三、 索引使用的注意事項

   磁碟佔用
   對dml(update,delete,insert)語句的效率影響
   頻繁操作的適合建立索引,欄位非頻繁不適合建立索引,更新次數多的不適合建立索引
   
   
   說明,如果我們的表中使用有複合索引(索引作用在多列上),此時我們
   注意
   1>對於建立得多列索引,只要查詢條件使用了最左邊的列,索引一段就會
   被使用。
       explain select * from dept where  loc ="xxx"
    2>對於使用like查詢,查詢如果是'%AA' 不會使用到索引‘aaa%’
        會使用到索引

比如: explain select * from dept where dname like '%AAA'
不能使用 索引,既在like查詢時,關鍵字,最前面,不能使用%或則)_這樣
的字元,如果一定要前面有變化的值,則考慮使用全文檢索->sphinx

3>如果條件中有or 即使用其中有條件帶索引也不會使用,換言之,就是
要求使用所欄位,都必須建立索引
 
 

id : 查詢序列號
select_type:查詢的型別
table:查詢的表名
type:掃描的方式 
possible_keys:這個表中可能使用了哪些索引
key 實際使用了哪些索引
key_len: 
ref
rows:掃描了多少行數,可能得到多少記錄
extra:sql語句額外資訊,排序方式

索引的使用
    檢視索引的是使用情況
         show status like  'Handler_read%';
         大家可以注意
         handler_read_key:這個值越高越好,越高表示使用索引查詢到的次數
         handler_read_rnd_next:這個值越高,說明查詢低效


常用SQL優化
    大批量插入資料(MySql管理員)
    對於MyISAM
    alter table table_name disable keys
     loading dataa
     alter table table_name enable keys;
     對於Innodb
     對於
     1.將到匯入的資料按照主鍵排序
     2.set unique_checks= 0,關閉唯一性校驗
     3. set autocommit = 0,關閉自動提交
     
sql語句的小技巧

    1>   在使用group by 分組查詢,預設分組後,還會排序,可能會降低速度
    2>   在group by 後面新增order by null 就不會排序
    3>    在有些情況下,可以使用連線代替子查詢,因為使用join MySql不需要在記憶體中
            建立臨臨時表
            
            select * from dept,emp where dept.deptno = emp.deptno
            
            select * from dept left    join  emp    on   dept.deptno = emp.deptno


選擇合適的儲存引擎
    
       myIsam  儲存,如果表對事物要求不高,同時是以查詢和新增為主的,我們考慮使用
                      myisan儲存引擎
       
       
      INNODB 儲存,對事物要求高,儲存的資料都是重要資料
      
      memory: 儲存,比如我們資料變法頻繁,不需要入庫,同時又頻繁查詢和修改,我們考試
                        使用memory
    
                         myisam       innodb  
  
   批量插入的速度    高             低
   事物安全                               支援
   全文索引               支援
   鎖機制                  表鎖         行鎖
   儲存限制               沒有         64TB
   B數索引                沒有         支援
   雜湊索引                               支援
   叢集索引                               支援
   資料快取               支援          支援
   索引快取               支援
   資料可壓縮            支援
   空時使用                低               高
   記憶體使用                 低              高
   支援外來鍵                                 

MyISaM 與 innodb

1.事物安全
2.查詢和新增速度
3.支援全文索引
4.鎖機制
5.外來鍵MyISAM不支援外來鍵

MyISaM刪除資料檔案變小
optimize table 表名

定時維護

三、資料庫備份

一、手動資料庫(表的)方法

cmd 控制檯

   mysqldump -uroot -proot 資料庫[表名1 表名2] > 檔案路徑
   比如 吧temp 資料庫備份到d \temp bak
   mysqldump -u root -proot temp>d:\temp.bak

二、如何使用備份檔案恢復我的資料

在mysql環境

   source d:\temp.bak 

使用定時器來定時完成

   一、在windows系統
         mytask.bak 檔案
               mysqldump -u root -proot temp>d:\temp.bak
   注意:
            注意
                  1>   如果路徑裡面有空格需要加入雙引號
                  2>   mysqlump 寫全路徑
         定時任務
                 windwxp
                    控制面板---> 任務計劃

二、在linux系統

    現在問題是,每次都是覆蓋原來的備份檔案,不利用我們分時間段進行備份,
      crontab  corn 表示式

理解事務的4種隔離級別 讀

1.Read uncommitted (髒讀)

 讀未提交
        就是一個事務可以讀取另一個未提交事務的資料。

2.Read committed (不可重複讀) 讀取兩次資料不一致

   讀提交,顧名思義,就是一個事務要等另一個事務提交後才能讀取資料。
   如果對事物進行update操作時,讀操作事物要等待這個更新操作事物提        交後才能讀取資料,可以解決髒讀問題

3.Repeatable read (幻讀)讀取兩次資料一致

  重複讀,就是在開始讀取資料(事務開啟)時,不再允許修改操作
  不可重複讀對應的是修改,即UPDATE操作。但是可能還會有幻讀問題。因為幻讀問題對應的是插入INSERT操作,而不是UPDATE操作。

4.Serializable 序列化

Serializable 是最高的事務隔離級別,在該級別下,事務序列化順序執行,可以避免髒讀、不可重複讀與幻讀。但是這種事務隔離級別效率低下,比較耗資料庫效能,一般不使用。

一、什麼資料庫的事物
原子性、一致性、格力性、永續性

   原子性(ATOMICITY)
              一個事物必須視為一個不可分割的最小工作單元,整個事物中額所有操作
         要麼全部提交成功,要麼全部失敗,對於一個事物來說,不可能只執行其中
         一部分操作。
   
   一致性
             一致性是指事物將資料庫從一種一致性狀態裝換到另外一種一致性狀態
             ,在事物開始之前和事物結束後資料庫中資料的完整性沒有破壞。
             
             
    事物的隔離型(ISOLATION)        
           隔離性要求一個事物對資料庫中資料的修改沒再未提交完成前對於其他事物
           是不可見的
           
           
   事物的永續性
         一旦事物提交,則其所做的修改就會永遠儲存到資料庫中

什麼是大事物
執行事物比較長,操作的資料比較多的事物
風險
鎖定太多的資料、造成主從延遲大量的阻塞和鎖超時回滾時所需時間比較長
回滾時所需時間比較上
執行時間長、容易造成主從延遲
1.避免一次處理大多的資料
2.移除不必要的查詢操作

十、影響資料庫效能

一、磁碟IO

  風險
         磁碟IO效能突然下降(使用更快的磁碟裝置)
         其他大量消耗磁碟效能的計劃任務(調整計劃任務,做好磁碟維護)

二、QPS和TPS

三、網絡卡流量

如何避免無法連線資料庫的情況

    1.減少從伺服器的資料
    2.進行分級快取
    3.避免使用select * 進行查詢
    4.分離業務網路和伺服器網路

四、大表

一、可以稱為大表
   1.記錄行數巨大,單表超過千萬行
   2.表的額資料檔案巨大,表資料檔案超過10G

二、大表查詢的影響

 慢查詢:很難在一定的時間內過濾出所需要額資料
 
  
 大表對DDL操作影響
      風險
           MySQL版本< 5.5 建立索引會鎖表
           MySQL版本 > = 5.5雖然不會鎖表但會引起主從延遲
      
      修改表結構需要長時間鎖表
             長時間的主從延遲
             影響正常的資料操作
      
        如何處理資料庫中的大表
            分庫分表把一張大表分成多個小表
               難點
                    分表主鍵的選擇
                    分表後跨跨分割槽資料的查詢和統計    
              
              大表的歷史資料歸檔
                    減少對前端後端業務的影響
                    難點
                         1.歸檔的時間點的選擇
                         2.如何進行歸檔操作

一、把一個例項中多個數據庫查分到不同的例項

   例如
          MySQL節點一
                  訂單 ---------使用者---------------促銷
                  訂單節點node01
                  使用者節點node02
                  促銷節點node03
        
        不能解決寫負載----->

二、把一個庫中表分離到不同的資料庫中

   訂單節點node01  拆分到不同的節點中
           訂單表
           商品表
           購物表

三、資料庫分片前的準備

        如何選擇分割槽鍵
             1.要儘量避免跨分割槽查詢的發生
             2.分片鍵要儘可能使各個分片中的資料平均
        
        如何無需分片的表
                每個分片中儲存一份相同的資料
                使用額外的節點統一儲存
            
         如何在節點上部署分片
              在每個分片使用單一資料庫。並且資料庫也相同
              將多個分片儲存在一個數據庫中,並在表名上加入分片號字尾
              在一個節點中部署多個數據庫,每個資料庫包含一個分片

資料庫分片前的準備
如何分配分片中的資料
按分割槽鍵的Hash值取模來分配分片資料
按照區鍵的範圍來分配分片資料
利用分割槽鍵和分片的對映表來分配分片資料