MySQL 第八天(核心優化二)

一.昨天內容回顧

  1. 存儲引擎

    保存數據的格式(技術),不一樣格式體現特性不同 php

    myisam mysql

    ① 結構、數據、索引 文件單獨存儲 redis

    ② 存入數據順序(不考慮主鍵順序) ,寫入數據速度快 算法

    ③ 併發性,低,鎖整張表 spring

    ④ 壓縮機制 sql

    innodb 數據庫

    結構有單獨文件,數據索引合併到一個文件中 緩存

    (經過設置,能夠給每一個表設置一個"數據/索引"文件) 服務器

    ② 存入數據順序(給考慮主鍵值的前後順序,數值大小排序存儲) 數據結構

    ③ 併發性,高,鎖行

  2. 字段選擇

    ① 字段選取佔據空間小的(bigint int mediumint smallint tinyint)

    ② 內容長度固定,選取char類型使用 varchar()

    ③ 數據最好存儲爲整型的(時間set/enum、ip地址)

  3. 逆範式

     

  4. 索引

    索引是數據結構,其內部有算法(規律、規則)

    1. 四種類型、建立、刪除

    四種:主鍵、惟一[例如用戶名惟一]、普通、全文索引 ,複合索引

    1. 執行計劃

    針對查詢select語句起做用

    sql語句在沒有執行以前把全部須要的資源都準備好,咱們能夠預先 查看下

    咱們關心sql語句是否用到索引

    explain sql語句\G;

    1. 適合場合

    ① where

    ② 排序字段

    select * from 表名 order by 字段 limit 1000000,50; 不會用索引

    select * from 表名 order by 字段 limit 50; 用索引

    select * from 表名 order by 字段 limit 100,50; 用索引

    select * from 表名 order by 字段 limit 偏移量,50; 用索引

    偏移量若是超過10萬,就不會使用索引。

    ③ 索引覆蓋

    ④ 連表查詢,外鍵設置索引

    1. 使用原則

    ① 字段獨立

    ② 左原則(模糊查詢)

    ③ 複合索引

    ④ or原則

  5. 索引

    1. 設計依據

    ① 被頻繁使用的字段設置索引

    字段被頻繁用在whereorder等條件裏邊。

    數據表建立完畢,要預估那些字段被常用,就給其建立索引

    ② 執行時間長的sql語句考慮設計索引

    能夠利用"慢查詢日誌"收集這樣的sql語句並優化設計索引

    ③ 邏輯很是重要的sql語句考慮設計索引

    例如商城系統裏邊,會員給本身帳戶充值就比較重要

    還有會員下訂單購物,進行付款的時候也比較重要。

     

    ④ 字段內容足夠花樣化,能夠考慮設計索引

    反面教材,性別不能設計索引(內容的取值很是少)

    2. 前綴索引

    什麼是前綴索引:

    若是一個字段的內容的前邊的n位信息已經足夠能夠標識當前的字段內容,就能夠把字段的前n位得到出來並建立索引,

    經過字段內容前n位建立的索引就稱爲"前綴索引"。

     

    例如:

    紀無

    雲斐

     

     

    以上字段內容,經過前1位,就能夠惟一標識當前字段內容,這樣就把前1位取出來建立索引

    好處:索引佔據的物理空間要比較小,這樣的索引運行速度快、效率高,對mysql總體性能提高有很大幫助。

     

    具體操做:

    alter table 表名 add key (字段(位數))

     

    思考:

        究竟是前幾位能夠標識當前字段內容

        經過substring得到字段的前n爲信息,從1開始遞增時獲取

        獲取的時候去除重複的,計算總個數,不斷增長n的數值,直至總個數穩定

        此時n的數值就是適合作"前綴索引"的數字。

     

        索引是給sql語句作優化

        前綴索引,是給索引作的優化

     

        得到字段的前n位:substring(字段,開始位置,長度n) mysql函數

    同上上圖能夠知道,經過前11位,能夠給epassword字段設置索引。

     

     

    3. in條件索引使用

    4. 全文索引

    什麼是全文索引:

    其餘索引是把字段的內容做爲一個總體進行索引設計

    全文索引,相似咱們有一篇做文,把做文中的一些關鍵字給獲取出來當成是索引內容。

    具體理解,就是作like模糊查詢,相似baidu搜索一些關鍵字效果。

     

     

     

     

     

    全文索引注意:

    ① 字段類型必須爲varchar/char/text類型

    ② mysql 5.6.4以前只有Myisam支持,5.6.4以後則Myisaminnodb都支持。

    ③ mysql中的全文索引目前只支持英文(不支持中文),若是須要支持中文可使用sphinx

    ④ 現實生產中mysql的全文索引不常用,sphinx常使用

    mysql全文索引自做聰明,對關鍵字的收錄有本身的考慮。

     

    版本是5.5.27,所以只有Myisam支持全文索引。

     

     

    4.1 具體操做

    CREATE TABLE articles (

    id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,

    title VARCHAR(200),

    body TEXT

    )engine=myisam charset utf8;

     

    INSERT INTO articles (title,body) VALUES

    ('MySQL Tutorial','DBMS stands for DataBase ...'),

    ('How To Use MySQL Well','After you went through a ...'),

    ('Optimizing MySQL','In this tutorial we will show ...'),

    ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),

    ('MySQL vs. YourSQL','In the following database comparison ...'),

    ('MySQL Security','When configured properly, MySQL ...');

     

    alter table articles add fulltext index `index_body` (body);

     

    如今已經有了一個index_body的全文索引:

    所以相似以下sql語句就可使用到索引了

    select * from articles where body like '%內容%';

    可是sql語句須要變形爲:

    select * from articles where match(字段body) against(內容);

     

    4.2 複合全文索引

    alter table articles add fulltext index `index_fu` (title,body);

     

    select * from articles where title like '%內容%' and body like '%內容%'

     

    5. 索引結構(瞭解)

    索引的數據結構

    主要討論兩種:Myisam 和 Innodb

    Mysql的數據結構都是B+tree結構

     

    數據結構:數據以一種規律的、規則的方式組織在一個格式裏邊,能夠保證咱們得到數據的快速性。

    5.1 Myisam索引結構

    該Myisam索引結構稱爲"非聚合型"

     

    上圖說明,主鍵內容在該索引裏邊經過算法開始被查詢、得到,並藉助"指針"向下級尋找,直到找到對應的葉子節點。

    葉子節點裏邊有該關鍵字對應的記錄的物理地址,進而得到對應的記錄信息。

     

    索引運行原理:快速定位主鍵id值,得到對應記錄物理地址,得到記錄信息。

     

    每一個主鍵id值都是一個節點,節點自己有指針。

    最底層的節點稱爲"葉子節點",該節點與記錄的物理地址直接聯繫

    上圖節點從上到下的層次數是索引結構的高度

    每層節點的數目稱爲結構的寬度

    結構的寬度、高度的數目由mysql底層算法計算得到(太高、過寬都不利於數據的快速獲取)

     

    Myisam其餘索引結構與主鍵索引結構一致。

     

    經過上圖索引結構,咱們看到了 索引部分 和 數據部分是分離的,它們之間經過物理地址進行聯繫。

     

    5.2 Innodb索引結構

     

    該Innodb索引結構稱爲"聚合型"

    聚合在:"索引"和"數據"是合併在一個文件裏邊的。

     

    下圖表示innodb的其餘索引(惟1、普通)

    該(用戶名字)其餘索引運行原理:

    ① 經過索引結構內部的算法快速定位該名字對應的"葉子節點"

    ② 葉子節點 裏邊對應的是關鍵字的記錄主鍵id

    ③ 經過記錄主鍵id值走主鍵索引便可

     

     

    innodb(主鍵)索引運行原理:

    ① 經過索引結構快速定位主鍵id值對應的"葉子節點"

    ② 該葉子節點 裏邊直接與整條記錄信息進行對應(而在Myisam裏邊,葉子節點與物理地址對應)

     

    innodb索引:

    普通索引關鍵字----->記錄的主鍵id值------>記錄的整條信息

     

    三.緩存設置

    有的被頻繁執行的sql語句,比較消耗時間、消耗系統資源(沒的優化可作)

    而且每次得到數據還不太發生變化

    那麼就把這個sql語句得到信息給緩存起來,供後續執行使用

    這樣很是節省系統資源。

    1. 具體使用

     

     

     

     

  6. 緩存失效

    數據表的數據有變化 或者 數據表結構有變化,則緩存失效。

     

    3. 什麼狀況不使用緩存

    sql語句每次得到數據有變化。

    例若有 時間信息、隨機數等

     

    4. 生成多個緩存

    生成緩存的sql語句對"空格"、"大小寫"比較敏感

    相同結果的sql語句,因爲空格、大小寫問題就會分別生成緩存。

     

    5. 不使用緩存

    sql_no_cache 不進行緩存

     

    6. 查看緩存空間使用狀況

     

    總結:

  7. 索引依據:頻繁、時間長、邏輯重要
  8. 前綴索引
  9. 全文索引(搜索引擎 baidu google 數據檢索)
  10. 索引結構:Myisam innodb(主鍵、其餘索引)
  11. 緩存設置

     

    四.分表設計

    一個數據表裏邊存儲的記錄信息太多了,記錄的條數達到1-2億條信息。

    這時該數據表的活性就大大下降,數據表的運行速度就比較慢、效率低下,影響mysql數據庫的總體性能。

    如今設置一個水平分割,把許多的記錄信息分別存儲到不一樣的數據表裏邊,這樣每一個表存儲的記錄就比較少,該表的活性大大提升。

     

    分表設計的兩種模式:

    ① 邏輯方式分表

        mysql數據庫自己就有分表技術,該方式的分表能夠節省php的邏輯處理

     

        

    ② 物理方式分表

        本身手動建立多個數據表出來

        php程序須要考慮分表算法:數據往哪一個表,從哪一個表

        

     

    1. 演示邏輯分表設計

    mysql自己就支持的分表技術

     

    以上邏輯分表設計,在php程序裏邊無需設置額外算法代碼,還像以往同樣直接對goods數據表進行操做便可,mysql自己會考慮分表的算法。

    2. 四種格式的邏輯分表

    具體爲:key hash ---->[求餘方式]

    range list ---->[範圍方式]

     

    注意:分表字段必須是主鍵 或 主鍵的一部分

    2.1 key分表

    partition by key(條件字段id) partitions 10;

    2.2 hash分表

    根據表達式/字段方式進行分表設計

    partition by hash(表達式/字段) partitions 數量;

     

     

     

     

     

     

    2.3 range分表

    根據 字段/表達式 是否知足某個範圍條件進行分表設計

    partition by range(year(pubdate))(

    partition hou70 values less than (1980),

    partition hou80 values less than (1990),

    partition hou90 values less than (2000),

    partition hou00 values less than (2010)

    )

     

     

    2.4 list分表

    根據 表達式/字段 的內容值是否在某個"列表"中進行分表設計。

    partition by list(month(pubdate))(

    partition spring values in (3,4,5),

    partition summer values in (6,7,8),

    partition autumn values in (9,10,11),

    partition winter values in (12,1,2)

    )

    3. 分表管理

    具體就是對已經存在的分表進行增長減小操做。

     

    增長分表 不會引發數據丟失。

    減小分表 在range/list領域形成數據丟失

    key/hash領域不會形成數據丟失,

             這兩個領域在進行減小分表的同時就把所有數據從新整合到存在的表中,

    key/hash兩種分表與業務邏輯關聯不緊密

     

    增長分表

        求餘方式: key/hash

        > alter table 表名 add partitions 數量;

     

        範圍方式: range/list

        > alter table 表名 add partition(

    partition 名稱 values less than (常量)

    partition 名稱 in (n,n,n)

    );

    3.2 刪除分表

    求餘方式(key/hash):

    >alter table 表名 coalesce partition 12;

    刪除分表不會形成數據丟失,每次分表數據都從新整合到存在的分表裏邊。

    範圍方式(range/list):

    >alter table 表名 drop partition 分區名稱;

    刪除分表會形成數據丟失

    ① key/hash方式不會丟失數據

     

    ② range/list會丟失數據

    給range分表寫4條記錄:

     

     

    把"hou80"的分區刪除,從下圖查詢結果看對應分表的數據也丟失了。

     

     

    4. 物理分表設計

     

    以上goods的物理分表須要增長php的算法邏輯:

    須要計算記錄從哪一個表、給哪一個表

    4.1 php對物理分表的操做

     

     

    5. 垂直分表

    水平分表:是把一個表的所有記錄信息分別存儲到不一樣的分表之中。

    垂直分表:是把一個表的所有字段分別存儲到不一樣的表裏邊。

     

    有的時候,一個數據表設計好了,裏邊有許多字段,可是這些字段有的是常用的,有的是不經常使用的。

    例如,一個數據表有20個字段,其中10個字段是經常使用的,後10個字段是不經常使用的

    那麼在操做經常使用字段的時候,就不得不給其餘不經常使用的字段也分配必定的資源進行操做。

     

    數據表:

    會員表user_id 登陸名 密碼 郵箱 手機號碼 身高 體重 性別 家庭地址 身份證號碼

    以上表,紅色是經常使用的,藍色的是不經常使用的

    爲了使得經常使用字段運行速度更快、效率更高,把經常使用字段給挑選出來,所以數據表作如下設計:

    會員表(主)字段:user_id 登陸名 密碼 郵箱 手機號碼

    會員表(輔)字段:user_id 身高 體重 性別 家庭地址 身份證號碼

     

    以上把會員表根據字段是否經常使用給分爲兩個表的過程就是垂直分表。

  12. 架構設計

    架構設計也稱爲集羣設計:由多臺mysql服務器共同支撐網站的運行,每臺服務器分擔的工做就比較少,運行速度快、效率高。

     

    mysql數據庫在運行的時候通常查詢/寫入的sql語句比例爲:7/1

    而且查詢消耗的資源比寫入要更多。

    所以能夠設計一個"主從模式"的集羣,與以前redis的主從模式使用模式一致。

     

    維護備份的集羣架構:

     

    主從模式的集羣架構:

    六.慢查詢日誌收集

    咱們要把系統裏邊一些執行速度很是慢的sql語句給收集起來,並作分析優化,使得其執行速度加快。

     

     

     

     

     

     

     

    總結:

  13. 水平分表設計

    分的是數據記錄

    1. 邏輯分表

    求餘:key/hash 範圍:range/list

    建立/增長分表:新建表時、分表建立完畢還能夠增長

    刪除分表:key/hash不會形成數據丟失

    range/list能形成數據丟失

     

    1. 物理分表

    php代碼須要增長算法邏輯

  14. 垂直分表

    分的是表的字段

     

  15. 架構設計

    架構集羣有兩種方式:

    ① 互爲備份

    ② 主從模式[經常使用]

  16. 慢查詢日誌收集
相關文章
相關標籤/搜索