04: Mysql性能優化

MySQL其餘篇

目錄:

參考網站html

1.1 Mysql數據庫的優化技術     返回頂部

  一、mysql優化是一個綜合性的技術,主要包括mysql

      1. 表的設計合理化(符合3NF)
      2. 添加適當索引(index) [四種: 普通索引、主鍵索引、惟一索引unique、全文索引]
      3. 分表技術(水平分割、垂直分割)
      4. 讀寫[寫: update/delete/add]分離
      5. 存儲過程 [模塊化編程,能夠提升速度]
      6. 對mysql配置優化 [配置最大併發數my.ini, 調整緩存大小 ]
      7. mysql服務器硬件升級
      8. 定時的去清除不須要的數據,定時進行碎片整理(MyISAM)算法

  二、要保證數據庫的效率,要作好如下四個方面的工做sql

      1. 數據庫設計
      2. sql語句優化
      3. 數據庫參數配置
      4. 恰當的硬件資源和操做系統數據庫

      此外,使用適當的存儲過程,也能提高性能。
      這個順序也表現了這四個工做對性能影響的大小編程

1.2 數據庫表設計      返回頂部

  一、通俗地理解三個範式數組

      第一範式: 1NF是對屬性的原子性約束,要求屬性(列)具備原子性,不可再分解;(只要是關係型數據庫都知足1NF)緩存

      第二範式: 2NF是對記錄的唯一性約束,要求記錄有唯一標識,即實體的唯一性;服務器

      第三範式: 3NF是對字段冗餘性的約束,它要求字段沒有冗餘。 沒有冗餘的數據庫設計能夠作到。mysql優化

   二、第一範式(1NF)

      1. 即表的列的具備原子性,不可再分解,即列的信息,不能分解, 只要數據庫是關係型數據庫(mysql/oracle/db2/informix/sysbase/sql server),就自動的知足1NF。
      2. 數據庫表的每一列都是不可分割的原子數據項,而不能是集合,數組,記錄等非原子數據項。
      3. 若是實體中的某個屬性有多個值時,必須拆分爲不一樣的屬性 。通俗理解即一個字段只存儲一項信息。

  三、第二範式(2NF)

      一、要求數據庫表中的每一個實例或行必須能夠被唯一地區分。爲實現區分一般須要咱們設計一個主鍵來實現(這裏的主鍵不包含業務邏輯)。

  四、第三範式(3NF)

      一、要求一個數據庫表中不包含已在其它表中已包含的非主鍵字段。
      二、若是可以被推導出來,就不該該單獨的設計一個字段來存放(能儘可能外鍵join就用外鍵join)。
      三、不少時候,咱們爲了知足第三範式每每會把一張表分紅多張表。

1.3 SQL優化

一、爲查詢緩存優化你的查詢     返回頂部

    一、大多數的MySQL服務器都開啓了查詢緩存。這是提升性最有效的方法之一,並且這是被MySQL的數據庫引擎處理的。
    二、當有不少相同的查詢被執行了屢次的時候,這些查詢結果會被放到一個緩存中,這樣,後續的相同的查詢就不用操做表而直接訪問緩存結果了。
    三、像 NOW() 和 RAND() 或是其它的諸如此類的SQL函數都不會開啓查詢緩存,由於這些函數的返回是會不定的易變的。

二、EXPLAIN 你的 SELECT 查詢     返回頂部

  一、explain關鍵字做用

      一、使用 EXPLAIN 關鍵字可讓你知道MySQL是如何處理你的SQL語句的。這能夠幫你分析你的查詢語句或是表結構的性能瓶頸。
      二、EXPLAIN 的查詢結果還會告訴你你的索引主鍵被如何利用的,你的數據表是如何被搜索和排序的……等等,等等。

  二、explain使用舉例

      Explain select * from emp where ename=「wsrcla」
      會產生以下信息:
        select_type: 表示查詢的類型。
        table:  輸出結果集的表
        type:  表示表的鏈接類型
        possible_keys:   表示查詢時,可能使用的索引
        key:   表示實際使用的索引
        key_len:   索引字段的長度
        rows:   掃描出的行數(估算的行數)
        Extra:   執行狀況的描述和說明

  三、EXPLAIN信息詳解

    1. id   SELECT識別符。這是SELECT的查詢序列號

    2. select_type 

        PRIMARY :   子查詢中最外層查詢
        SUBQUERY :    子查詢內層第一個SELECT,結果不依賴於外部查詢
        DEPENDENT SUBQUERY:   子查詢內層第一個SELECT,依賴於外部查詢
        UNION :   UNION語句中第二個SELECT開始後面全部SELECT,
        SIMPLE:  簡單的 select 查詢,不使用 union 及子查詢
        UNION :  UNION 中的第二個或隨後的 select 查詢,不依賴於外部查詢的結果集

    3. Table : 顯示這一步所訪問數據庫中表名稱

    4. Type : 對錶訪問方式

        ALL:  SELECT * FROM emp \G 完整的表掃描 一般很差
        SELECT * FROM (SELECT * FROM emp WHERE empno = 1) a ;
        system:  表僅有一行(=系統表)。這是const聯接類型的一個特
        const:  表最多有一個匹配行

    5. Possible_keys : 該查詢能夠利用的索引,若是沒有任何索引顯示  null

    6. Key : Mysql 從 Possible_keys 所選擇使用索引

    7. Rows :  估算出結果集行數

    8. Extra查詢細節信息
        No tables :  Query語句中使用FROM DUAL 或不含任何FROM子句
        Using filesort :  當Query中包含 ORDER BY 操做,並且沒法利用索引完成排序,
        Impossible WHERE noticed after reading const tables: MYSQL Query Optimizer
        經過收集統計信息不可能存在結果
        Using temporary:  某些操做必須使用臨時表,常見 GROUP BY ; ORDER BY
        Using where:  不用讀取表中全部信息,僅經過索引就能夠獲取所需數據;

三、 當只要一行數據時使用 LIMIT 1     返回頂部

    一、當你查詢表的有些時候,你已經知道結果只會有一條結果,但由於你可能須要去fetch遊標,或是你也許會去檢查返回的記錄數。
    二、在這種狀況下,加上 LIMIT 1 能夠增長性能。這樣同樣,MySQL數據庫引擎會在找到一條數據後中止搜索,而不是繼續日後查少下一條符合記錄的數據。

四、創建適當的索引      返回頂部

  一、索引爲什會使查找變快

      一、btree類型的索引,就是使用的二分查找法,確定快啊,算法複雜度是log2N,也就是說16條數據查4次,32條數據查5次,64條數據查6次....依次類推。
      二、使用索引跟沒使用索引的區別,就跟咱們使用新華字典查字,一個是根據拼音或者筆畫查找,一個是從頭至尾一頁一頁翻。

  二、索引的代價

      一、磁盤佔用
      二、對dml(update delete insert)語句的效率影響

  三、索引使用原則

      一、較頻繁的做爲查詢條件字段應該建立索引
          select * from emp where empno = 1;

      二、惟一性太差的字段不適合單首創建索引,即便頻繁做爲查詢條件
          select * from emp where sex = '男'

      三、更新很是頻繁的字段不適合建立索引
          select * from emp where logincount = 1

      四、不會出如今WHERE子句中的字段不應建立索引

  四、mysql四種索引的區別

      一、主鍵索引,主鍵自動的爲主索引 (類型Primary)
      二、惟一索引 (UNIQUE)
      三、普通索引 (INDEX)
      四、全文索引 (FULLTEXT) [適用於MyISAM] ——》sphinx + 中文分詞 coreseek [sphinx 的中文版 ]
  五、索引的使用  

    1. 創建索引

        一、create [UNIQUE|FULLTEXT] index index_name on tbl_name (col_name [(length)] [ASC | DESC] , …..);
        二、alter table table_name ADD INDEX [index_name] (index_col_name,...)

    2.  刪除索引

        一、DROP INDEX index_name ON tbl_name;
        二、alter table table_name drop index index_name;

        注:刪除主鍵(索引)比較特別: alter table t_b drop primary key;

    3. 建立普通索引方法

      #1 查看student表中有哪些索引
          mysql> show index from student;                                   #查看student表中有哪些索引

      #2 建立最基本的的索引
          mysql> create index index_name on student(name(32));              #將student中字段name建立成索引

      #3 刪除索引的語法
          mysql> drop index index_name on student;

    4. 建立惟一索引
        注: 它與前面的普通索引相似,不一樣的就是:索引列的值必須惟一,但容許有空值
        #1建立索引
        mysql>  create unique index index_name on student(name(32));

  六、使用或不使用索引的狀況

    1. 下列幾種狀況下有可能使用到索引

        1,對於建立的多列索引,只要查詢條件使用了最左邊的列,索引通常就會被使用。
        2,對於使用like的查詢,查詢若是是  '%aaa' 不會使用到索引, 'aaa%' 會使用到索引。

    2. 下列的表將不使用索引

        1, 若是條件中有or,即便其中有條件帶索引也不會使用。
        2, 對於多列索引,不是使用的第一部分,則不會使用索引。
        3, like查詢是以%開頭
        4, 若是列類型是字符串,那必定要在條件中將數據使用引號引用起來。不然不使用索引。(添加時,字符串必須'')
        5, 若是mysql估計使用全表掃描要比使用索引快,則不使用索引。

1.4 MySQL中like模糊匹配爲什麼低效     返回頂部

  一、都不使用索引

      說明:不使用索引的時候普通查詢與like查詢的耗時至關,like略長,這也是必然的,由於它要進行額外的算法。

                    

  二、like不使用索引、普通查詢使用索引

              說明:使用索引後,普通查詢的耗時基本算是秒查,很是快;而like查詢仍是耗時一秒多。

                   

                  

  三、like查詢起始也可使用索引

      1)若是咱們查詢的時候寫成「like 'dd_'或者like 'dd%'」,這樣是能夠用到索引的,此時的查詢速度也會相對的快一點。

      2)若是查詢的時候寫成「 like '%dd'」,查詢字符串最前面就是模糊的沒法使用索引

                 

1.5 數據庫優化方案     返回頂部

    1. 優化索引、SQL 語句、分析慢查詢

    2. 設計表的時候嚴格根據數據庫的設計範式來設計數據庫

    3. 使用緩存,把常常訪問到的數據並且不須要常常變化的數據放在緩存中,能節約磁盤IO

    4. 優化硬件;採用SSD,使用磁盤隊列技術(RAID0,RAID1,RDID5)等;

    5. 採用MySQL 內部自帶的表分區技術,把數據分層不一樣的文件,可以提升磁盤的讀取效率

    6. 垂直分表;把一些不常常讀的數據放在一張表裏,節約磁盤I/O

    7. 主從分離讀寫;採用主從複製把數據庫的讀操做和寫入操做分離開來

    8. 分庫分表分機器(數據量特別大),主要的的原理就是數據路由

    9. 選擇合適的表引擎,參數上的優化

    10. 進行架構級別的緩存,靜態化和分佈式

    11. 不採用全文索引

1.6 數據庫怎麼優化查詢效率     返回頂部

    一、儲存引擎選擇:若是數據表須要事務處理,應該考慮使用InnoDB,由於它徹底符合ACID特性。若是不須要事務處理,使用默認存儲引擎MyISAM是比較明智的

    二、分表分庫,主從。

    三、對查詢進行優化,要儘可能避免全表掃描,首先應考慮在 where 及 order by 涉及的列上創建索引

    四、應儘可能避免在 where 子句中對字段進行 null 值判斷,不然將致使引擎放棄使用索引而進行全表掃描

    五、應儘可能避免在 where 子句中使用 != 或 <> 操做符,不然將引擎放棄使用索引而進行全表掃描

    六、應儘可能避免在 where 子句中使用 or 來鏈接條件,若是一個字段有索引,一個字段沒有索引,將致使引擎放棄使用索引而進行全表掃描

    七、Update 語句,若是隻更改一、2個字段,不要Update所有字段,不然頻繁調用會引發明顯的性能消耗,同時帶來大量日誌

    八、對於多張大數據量(這裏幾百條就算大了)的表JOIN,要先分頁再JOIN,不然邏輯讀會很高,性能不好。

相關文章
相關標籤/搜索