zoukankan      html  css  js  c++  java
  • mysql基础知识与优化总结

    1. Mysql事务的四大特性

    事务:就是针对数据库的一组操作,他可由多条sql语句组成,且每个SQL相互依赖。只要程序在执行过程中有一条SQL执行失败,则其他语句都不会执行。

    Mysql的事务要求必须满足A,C,I,D这4个基本特性。

    • A-原子性:事务中的sql要么同时成功,要么同时失败。
    • C-一致性:事务前后,数据总量保持不变。
    • I-隔离性:各个事务相互隔离,互不干扰【当一个事务在执行时,不会受到其他事务的影响,保证了未完成事务的所有操作与数据库系统的隔离,直到事务完成为止,才能看到事务的执行结果】
    • D-持久性:事务成功提交后,数据会永久性的保存下来。

    注意:Mysql的事务默认是自动提交,如果没有主动关闭事务提交,每条SQL都会自动提交。

    注意:Mysql5.7默认的存储引擎为InnoDB,该存储引擎支持事务。而常见的另一个存储引擎MyISAM不支持事务。

    1.1 Mysql的保存点(补充)

    在回滚事务时,事务内的所有操作都将撤销。若希望只撤销一部分,可以用保存点来实现,使用以下语句可以在事务中设置一个保存点

    
    在事务中设置一个保存点
    savepoint 保存点名;
    
    在使用保存点后,使用以下语句可将事务回滚到指定保存点
    rollback to savepoint 保存点名;
    
    若不再需要保存点,使用以下语句删除保存点
    release savepoint 保存点名;
    
    //一个事务可以创建多个保存点,在提交事务后,事务中的所有保存点就会被删除。另外,在回滚到某个保存点后,在该保存点之后创建的保存点也会消失。//
    

    1.2 Mysql的锁机制(补充)

    不加锁出现的问题:
    同一时刻,用户A,B同时要去修改同一个表的同一个数据。比如:A用户:将User表的age值10改为20,B用户:将User表的age值10改为30。

    再不加锁的情况下和关闭mysql的自动提交功能情况下:
    当A改了age为20,还没提交。与此同时B获取到此时User表的age值为10。

    锁机制:用于解决多个事务操作同一个数据时存在的问题。在A事务进行操作时,锁住该资源,不准其他事务操作。

    在Mysql中,根据存储引擎的不同,分为如下锁类型:

    • 行级锁:仅锁定用户操作所涉及的记录行。【InnoDB采用】
    • 表级锁:锁定用户操作行所在的整个数据表。【MyISAM采用】

    锁等待:指一个线程等待其他线程释放锁的过程。
    数据表的死锁:两个或多个线程在互相等待对方释放锁而出现的一种"僵持"状态,若无外力作用,他们将永久处于锁等待的状态。



    2. 事务的隔离级别

    隔离级别:Mysql允许多线程并发访问,隔离级别时为了保证这些事务之间不受影响而存在的。

    • 读未提交:【脏读,幻读,不可重复读】
    • 读已提交:【幻读,不可重复读】SQLSever,Oracle的默认隔离级别
    • 可重复读:【幻读】Mysql的默认隔离级别,Mysql的InnoDB存储引擎通过多版本并发控制机制解决了幻读的问题
    • 串行化:事务的最高隔离级别,会在每个读的数据上加锁,解决了所有问题。由于加锁,导致性能低。

    ==============================

    • 脏读:一个事务可以读取到另一个事务还没提交的数据
    • 幻读:一个事务内的两次查询数据不一致。幻读是由于其他事务做了插入记录的操作
    • 不可重复读:一个事务内的多次查询结果不一致。不可重复读是由于查询过程中数据被其他事务进行了修改


    3. 存储引擎

    存储引擎:可以看作是数据表存储数据的一种格式,不同的格式具有的特性也不相同。在创建数据表时,选择合适的存储引擎则会对整体系统和性能产生巨大影响。

    InnoDB:Mysql5.7版本中被指定为默认的存储引擎,用于完成事务,回滚等事务的安全处理。
    特点:提供了良好的事务管理和并发控制。但是读写效率一般。

    MyISAM:Mysql5.5以前的版本的默认存储引擎,不支持事务。
    特点:不支持事务和并发性,但是读写效率快。

    常见的存储引擎:




    4. 完整SQL语法

    select * from user where group by having order by limit



    5. delete与truncate区别

    delete:删除表中所有记录,有多少删多少,不会改变表结构。若:id为自增,则自增不会变为0。
    truncate:删除表,自动重新创建一个一摸一样的表。若:id为自增,则自增会变为0。



    6. varchar与char区别

    varchar:可变字符串,长度可变。最多放65532个长度。存取慢,不占空间。
    char:定长字符串,长度不可变,你设置它多长,若他达不到,则会以空格进行填补。存取快,占空间。

    varchar(50):最多存放50个字符。存取慢。
    char(11):必须存11个字符,一般我们设置表的时候,可以将手机号设置为char(11)。存取快。【总的来说,只要你能很确定,这个字段存字符的大小,就可以优先考虑用char】



    7. count(*),count(1),count(column)的区别是啥

    • count(*):对行的数据进行计算,包含NULL
    • count(1):和上述一样
    • count(column):对特定列进行计算,不包含NULL


    8. Mysql实现乐观锁,悲观锁

    乐观锁:很乐观,每次拿数据都认为别人不会修改数据,不会上锁。在更新的时候再去判断在此期间别人是否更新了这个数据。
    实现方式:
    在表中加一个version字段,查询数据时得到它的值,更新时加上这个条件。

    悲观锁:很悲观,每次拿数据都任务别人肯定会修改数据,会上锁。在他拿到数据操作完之前,别人不能来操作数据。
    实现方式:

    1. 关闭事务的自动提交功能
    2. 在查询数据时加上“for update”



    9. 数据库优化

    前言:在开发中,我们要根据需求,合理安排资源,使MySQL运行更快。其中包括:建表时存储引擎的选择,索引的创建,SQL语句的优化,操作数据时锁机制的应用,分区分表技术的应用等。

    9.1 索引

    索引:一种特殊的数据结构,用于将表中某些字段与记录的位置建立一个对应关系,加快定位数据位置的时间。
    特点:加快查询效率。但不是越多越好,虽然提高了查询效率,但是为降低服务器的负载,建里索引也会占用物理存储空间,索引的维护也比较麻烦。
    分类:

    • 普通索引:可以创建多个。
    • 唯一索引:可以创建多个,但是创建的字段必须具有唯一约束。
    • 主键索引:一般不需要我们主动创建,只要在建表时指定了主建。主建索引只能有一个,不能为NULL, 没有索引名
    • 全文索引
    • 空间索引

    根据创建索引的字段个数,还阔以将其分为单列索引和复合索引。

    • 单列索引:指在表中单个字段上创建的索引,可以是普通索引,唯一索引,主建索引,全文索引
    • 复合索引:指在表中多个字段上创建一个索引,且只有在查询条件中使用了这些字段中的第一个字段时,该索引才会被使用(如:对name,age,address字段建立复合索引,在查询时,只有第一个字段被使用时,该复合索引才会被使用)。【多个字段的设置顺序要遵循“最左前缀原则”,就是把最频繁使用的字段放在最左边,然后依次类推】

    explain:SQL分析语句
    该关键字用于分析SQL语句的执行情况。


    索引的使用原则总结:
    1. 查询条件中频繁使用的字段才适合建立索引

    2. 比起字符串类型的字段,数字型的字段更适合建立索引

    3. 比起存储空间大的字段,存储空间较小的字段更适合建立索引

    4. 重复值字段高的字段不适合建立索引

    5. 更新频繁的字段不适合建立索引

    索引失效的情况总结

    可以使用explain命令加在要分析的sql语句前面,在执行结果中查看key这一列的值,如果为NULL,说明没有使用索引。

    1. mysql估计使用全表扫描比使用索引快时
      mysql估计使用全表扫描比使用索引快时,则不使用索引

    2. 查询时保证字段的独立
      对于建立索引的字段,在查询时要保证该字段在关系运算符(如:=,>等)的一侧独立,不能是表达式的一部分或函数的参数。
      如:select id from user where id+1 > 3;
      如:select name from user where ASB(id) = 1;

    3. 模糊查询中通配符的使用
      在模糊查询时,若匹配模式中的最左侧含有通配符(%),会导致全表扫描。如:select name from user where namke like "%飞";

    4. or条件查询
      在使用or查询时,只有or两边的字段都有索引,才会触发索引。

    5. 列类型为字符串
      比如列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引。

    6. 最左前缀原则
      复合索引没有使用最左前缀原则,则不会触发复合索引。

    7. 在索引字段上使用not,<>,!=。
      不会用到索引。 优化方法: key<>0 改为 key>0 or key<0。

    8. 在索引字段上使用in,not in
      in 和 not in 也要慎用,否则会导致全表扫描,如:select id from t where num in(1,2,3)。对于连续的数值,能用 between 就不要用 in 了。
      select id from t where num between 1 and 3

    9. 应尽量避免在 where 子句中对字段进行 null 值判断
      应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
      select id from t where num is null
      可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
      select id from t where num=0

    9.2 SQL优化

    参考:https://www.cnblogs.com/xc-chejj/p/11244748.html
    SQL优化,我们可以从数据表优化和sql语句优化入手。
    数据表优化:

    1. 选择合适的存储引擎。
    2. 列的字段能小就小,比如:年龄字段,可以设为thyint。以达到节省空间,提高查询效率。
    3. 不能为null的列,尽可能设置为不为NULL。
    4. 如果确认该字段是定长,用char。比如:手机号。
    5. 一个表字段不要太多,可以拆分成多张表。

    SQL语句优化:

    1. 不要使用select * 。阿里开发手册也这样说了的。尽量不要返回用不到的任何字段。不然会增加不必要的消耗(内存,CPU,宽带)
    2. 只需要查询一条数据是,可使用limit 1 提高查询。
    3. 要避免索引失效问题的出现。
    4. 避免联合查询,能改成单表查询,改成单表查询。
    5. 对于连续的数值,用between比用in效率高。能用between就不用in。
    6. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。

    9.3 分库分表

    https://www.cnblogs.com/itlihao/p/14803807.html

  • 相关阅读:
    lumen简单使用exel组件
    VIM 批量注释的两种方法 (转)
    linux时间校准 设置时间为上海时区
    lumen发送邮件配置
    centos 下安装redis 通过shell脚本
    shell 脚本接收参数
    linux设置系统变量
    linux通配符
    UCCI协议[转]
    一种编程范式:对拍编程
  • 原文地址:https://www.cnblogs.com/itlihao/p/14983582.html
Copyright © 2011-2022 走看看