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. 慢查询日志收集
相关文章
相关标签/搜索