Mysql数据库原理和数据优化

转载的原文位置
1、mysql常用的引擎
  1.1 InnoDB
    存储文件两个,".frm"表定义和".idb"数据文件
    存在表锁和行锁,不过行锁是在命中索引的情况下才会起作用
    支持事务,且支持四种隔离级别(读未提交、读已提交、可重复读、串行化),默认的为可重复读
    而在 Oracle 数据库中,只支持串行化级别和读已提交这两种级别,其中默认的为读已提交级别
    是以 ID 为索引的数据存储,通过 B+Tree 结构对 ID 建索引,然后在叶子节点中存储记录
  1.2 Myisam
    三个存储文件.frm表定义文件、.MYD数据文件、MYI索引文件
    只支持表锁,不支持事务
    数据读取方面性能很高
    数据与索引不在一起为非聚簇索引
    
  总结:InnoDB 和 Myisam 都是用 B+Tree 来存储数据的,目前常用的Mysql引擎是InnoDB,原因在于它支持行级锁、支持事务。
  
2、mysql B- B+ Tree
3、mysql 索引
  创建/增加索引
    1、创建表时创建
    2、CREATE INDEX
    3、ALTER TABLE
  普通索引、UNIQUE索引和PRIMARY KEY索引区别
  1、如果不允许重复值,则使用UNIQUE索引或PRIMARY KEY索引,否则用普通索引
  2、PRIMARY KEY索引是主键索引,一张表只有一个字段是PRIMARY KEY索引
  单字段索引创建:
    1.ALTER TABLE
      ALTER TABLE用来创建普通索引、UNIQUE索引或PRIMARY KEY索引。
        ALTER TABLE table_name ADD INDEX index_name (column_list)
ALTER TABLE table_name ADD UNIQUE (column_list)
        ALTER TABLE table_name ADD PRIMARY KEY (column_list)
    2.CREATE INDEX
      CREATE INDEX可对表增加普通索引或UNIQUE索引
        CREATE INDEX index_name ON table_name (column_list)
        CREATE UNIQUE INDEX index_name ON table_name (column_list)
    单字段索引删除:
      DROP INDEX index_name ON talbe_name
  组合索引
    复合索引创建:
      ALTER TABLE myIndex ADD INDEX name_city_age (Name(10),City,Age)
      about name一般情况下名字的长度不会超过 10,这样会加速索引查询速度,还会减少索引文件的大小,提高 INSERT 的更新速度
  **我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减
  索引分类:
    1、窄索引:指索引列为1-2列的索引
    2、宽索引:宽索引也就是索引列超过2列的索引
    重要原则:能用窄索引,就不用宽索引
  使用单字段索引的位置:
    1、表的主外键必须有索引
    2、数据量超300的表应该有索引
    3、经常于其他表进行关联的表,应该在连接字段建立索引
    4、经常出现Where子句的字段,特别是达标的字段,应该建立索引
    5、索引应该建立在选择性高的字段上
    6、索引应该建立在小字段上,对于大的文本字段甚至超长字段,不要建立索引
    7、复合索引的建立应该仔细分析,尽量使用单字段索引代替
  使用复合索引:
    复合索引的字段是否经常同时以and的方式出现在Where字句中,单字段查询是否极少甚至没有
    多个字段是or的加索引无用
  mysql单次查询只能使用一个索引,多个and查询时,复合索引会极大提升速度
  复合索引和单索引
  1、两个关联度较低的and连接语句,复合有优势
  2、两个关联度较高的and连接语句,复合有很大优势
  3、两个or连接的条件语句,单索引有优势,复合索引导致全表查询
    而且单索引可以 index merge优化
  4、索引注意事项
    1、频繁操作 增删改
    2、删除无用索引
3、Mysql索引命中规范
  1、最左匹配原则
    先定位该sql的查询条件,有哪些
4、索引分类
  1、聚簇索引MyISAM (顺序)
    表存储数据按照索引顺序存储,检索效率高,更新影响大
    注意:采用innoDB存储引擎的数据库,表一定要设置自增列作为主键,这样才能提高数据查询以及插入的效率
  2、非聚簇索引InnoDB (链表指针)
    数据存储一个地方,索引存储一个地方,索引带指针指向存储位置。检索效率低,对数据更新影响较小
5、Mysql调优
  1、建立适当的索引
    过度索引:性别只有两个值,创建索引反而会影响更新速度
    适合:经常操作/比较/判断
  2、适当的适用复合索引代替单索引
    mysql单次只能使用一个索引
    组合索引 A,B,C 相当于创建了 ABC AB A 三个索引。成为最佳左前缀特性
    创建组合索引是,应将最常用的放在最左边,依次递减
  3、索引不会包含NULL值,索引列不应为空
  4、使用短索引
  5、不鼓励like查询,非用不可的话左匹配(aaa%)好于全匹配(%aaa%)右匹配(%aaa)
  6、不使用NOT IN 使用 NOT EXISTS 替代
  7、开启缓存(使用缓存时,避免使用sql函数)
  8、表设计、垂直分割、固定表和变长表分割
  9、读写分离
  10、使用redis或者memache作为缓存层
  11、limit分页机制优化 (limit会扫描不必要的数据)
    1、查询字段加索引
    2、主键条件做设定,记住主键位置再取行
  12、经常需要联合查询的表,可以建立中间表以提高查询效率
6、数据库的事务性质
  1、原子性 操作要么全部发生,要么全部不发生
    redo(保存最新数据) log实现
  2、一致性 在事务开始前和结束后,数据库的完整性约束没有被破坏
    通过undo(备份旧数据)来实现
  3、隔离性 隔离状态执行事务,使他们好像是系统在给定时间内执行的唯一操作
    通过锁实现
  4、持久性 事务结束后,数据库的更改不会回滚
    redo log实现
7、mysql的并发控制与加锁分析
  MVCC
    悲观机制 基于锁的并发控制机制
      锁是预防性的,读会阻塞写,写会阻塞读
    MVCC 称为乐观机制
      后验证,互相不堵塞,提交是才验证是否有冲突
  隔离级别
    四种隔离级别。每一种级别都规定了,在一个事务中所做的修改,哪些在事务内和事务间是可见的,哪些是不可见的
    如果不考虑隔离性,事务存在3种并发访问问题:
      1、脏读(dirty read):两个事务,一个事务读取到了另一个事务未提交的数据,这便是脏读
      2、不可重复读:一个事务中两次读取的数据的内容不一致
      3、幻读(phantom read)
      其他事务的提交会影响在同一个事务中的重复查询结果。(一个事务中两次读取的数据的数量不一致 。因为另一个事务是insert操作)
      
      READ UNCOMMITTED (未提交读) :隔离级别:0. 哪个问题都不能解决
      READ COMMITTED (提交读) :隔离级别:1. 可以解决脏读。
      事务中只能看到已提交的修改,不保证事务重新读的时候能读到相同的数据
      REPEATABLE READ (可重复读) :隔离级别:2. 可以解决脏读和不可重复读,实现不幻读,需要加锁
      Mysql默认的隔离级别是RR REPEATABLE READ
      SERIALIZABLE (可串行化):隔离级别:3.
      该隔离级别会在读取的每一行数据上都加上锁,退化为基于锁的并发控制,即LBCC。可以解决脏读不可重复读和幻读—相当于锁表
    注意:MVCC只在RC和RR两个隔离级别下工作,其他两个隔离级别都和MVCC不兼容。
  死锁:当多个事务试图以不同的顺序锁定资源时,等待被锁定的资源时
8、Mysql 慢查询开启语句分析
  1、开始mysql慢查询
    1、修改my.ini文件
      [mysqlld]
      long_query_time = 秒数 查询过了多少秒算是慢查询
      日志记录位置5.0 5.1:
      log-slow-queries = “”
      日志记录位置5.5以上
      slow-query-log = ON
      slow_query_log_file = “”
      // 记录没有使用索引的查询
      log-query-not-using-indexes
    2、使用mysql数据库开启慢查询
      mysql>
      set global slow_query_log=ON
      set global log_query_time = 3600
      set global log_querise_not_using_indexes = ON
  2、查看慢查询数量
    show global status like ‘%slow%’
  3、分析慢查询日志
    explain 关键字分析
    explain + sql
    table 当前数据是哪张表的
    type 重要 显示连接使用了何种类型,
      最好到最差分别为:
      const>eq_reg>ref>range>indexhe>all
9、查询当前表的索引数
  show index from 表名称

猜你喜欢

转载自blog.csdn.net/u011008832/article/details/113657801