zoukankan      html  css  js  c++  java
  • 05 mysql索引

    1. 索引

    索引优化是对查询性能优化最有效的手段。索引能够轻易将查询性能提高好几个数量级。

    索引的目的在于提高查询效率。

    B+树结构。

    创建索引结构时,要使用区分度较高的字段那一列; 索引字段占用空间要尽量的小。

    在建表时,添加索引;不要在添加数据后,再添加索引,会将所有数据都会扫描,很慢。

    聚集索引 primary key

    1. 按照每张表的主键(primary key)构造一棵B+树,同时叶子结点存放的是行记录全部数据,也将聚集索引的叶子结点称为数据页,每个数据页都通过一个双向链表来进行链接。每张表只能拥有一个聚集索引。
    2. 如果未定义主键,MySQL取第一个唯一索引(unique)而且只含非空列(not null)作为主键,InnoDB使用它作为聚集索引。
    3. 如果都没有,InnoDB就自己产生一个这样的ID值,它有六个字节,而且是隐藏的,使其作为聚集索引。
    
    好处:
    	1.它对主键的排序查找和范围查找速度非常快,叶子节点的数据就是用户所要查询的数据。如用户需要查找一张表,查询最后的10位用户信息,由于B+树索引是双向链表,所以用户可以快速找到最后一个数据页,并取出10条记录。 
        2.范围查询(range query),即如果要查找主键某一范围内的数据,通过叶子节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可。
    	
    

    聚集索引的添加方式:

    # 两种创建方式:
    create table t1(id int primary key,);
    create table t1(id int,primary key(id));
    
    # 表创建后添加索引
    alter table 表名 add primary key(id);
    # 删除索引
    alter table 表名 drop primary key;
    

    辅助索引

    where 后面写其它字段条件,比如 ...where name=‘xxx’,没有用主键索引,这时候就需要给name字段添加辅助索引,加速查询。
    
    除了聚集索引以外的其他索引都是辅助索引,也称非聚集索引。
    与聚集索引区别是:辅助索引的叶子节点不包含行记录的全部数据,只存放对应字段与它的值,以及主键的值。如{'name字段',name的值,主键id值}这样一个标签。
    

    唯一索引 unique

    create table t1(id int unique);
    create table t1(id int,unique key u_name(id));	# 给这个索引起u_name名字
    
    # 表创建后添加索引
    alter table s1 add unique key u_name(id);
    # 删除索引
    alter table s1 drop index u_name;
    

    普通索引:

    # 创建
    create table t1(id int,index index_name(id));
    alter table s1 add index index_name(id);
    creatr index index_name on s1(id);
    
    # 删除
    alter table s1 drop index u_name;
    drop index 索引名 on 表名;
    

    覆盖索引:

    InnoDB存储引擎支持覆盖索引(covering index,或称索引覆盖),即从辅助索引中就可以得到查询记录,而不需要查询聚集索引中的记录。

    好处:辅助索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作。

    联合索引:最左原则。(联合主键/唯一/普通等)

    索引是有个最左匹配的原则的,所以建联合索引的时候,将区分度高的放在最左边,依次排下来,范围查询的条件尽可能的往后边放。

    creatr table t1(id int,name char(10),index index_name(id,name));
    

    正确使用索引

    并不是说我们创建了索引就一定会加快查询速度,若想利用索引达到预想的提高查询速度的效果,我们在添加索引时,必须遵循以下问题:
    1.范围问题,或者说条件不明确,条件中出现这些符号或关键字:>、>=、<、<=、!= 、between...and...、like
    范围越大,速度越小;
    	...where id=1000 比 ...where id>1000  要快。
    使用like时,通配符写在后面要比写在前面快。 'al%' > '%ex'
    
    2.尽量选择区分度高的列作为索引(树的高度较低),区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0。
    
    3.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。
    
    4. 索引列不能参与计算,保持列“干净“。
    
    5.and与or的逻辑
       条件1 and 条件2:所有条件都成立才算成立,但凡要有一个条件不成立则最终结果不成立
       条件1 or 条件2:只要有一个条件成立则最终结果就成立
       and:mysql会按照联合索引,从左到右的顺序找一个区分度高的索引字段(这样便可以快速锁定很小的范围),加速查询。
       or:mysql会按照条件的顺序,从左到右依次判断。
    6.最左前缀匹配原则,非常重要的原则,对于组合索引mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配(指的是范围大了,有索引速度也慢),比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
    

    查询优化神器——explain

    rows是核心指标,绝大部分rows小的语句执行一定很快.

    mysql> explain select * from s1 where id=10000;
    
    +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
    | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows    | Extra       |
    +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
    |  1 | SIMPLE      | s1    | ALL  | NULL          | NULL | NULL    | NULL | 2987134 | Using where |
    +----+-------------+-------+------+---------------+------+---------+------+---------+-------------+
    1 row in set (0.01 sec)
    

    2. mysql创建用户和授权

    对新用户增删改

    1.创建用户:
    # 指定ip:192.118.1.1的chao用户登录
    create user 'chao'@'192.118.1.1' identified by '123';
    # 指定ip:192.118.1.开头的chao用户登录
    create user 'chao'@'192.118.1.%' identified by '123';
    # 指定任何ip的chao用户登录
    create user 'chao'@'%' identified by '123';
    
    2.删除用户
    drop user '用户名'@'IP地址';
    
    3.修改用户
    rename user '用户名'@'IP地址' to '新用户名'@'IP地址';
    
    4.修改密码
    set password for '用户名'@'IP地址'=Password('新密码');
    
    

    对当前的用户授权管理

    #查看权限
    show grants for '用户'@'IP地址'
    
    #授权 chao用户仅对db1.t1文件有查询、插入和更新的操作
    grant select ,insert,update on db1.t1 to "chao"@'%';
    
    # 表示有所有的权限,除了grant这个命令,这个命令是root才有的。chao用户对db1下的t1文件有任意操作
    grant all privileges  on db1.t1 to "chao"@'%';
    #chao用户对db1数据库中的文件执行任何操作
    grant all privileges  on db1.* to "chao"@'%';
    #chao用户对所有数据库中文件有任何操作
    grant all privileges  on *.*  to "chao"@'%';
     
    #取消权限
     
    # 取消chao用户对db1的t1文件的任意操作
    revoke all on db1.t1 from 'chao'@"%";  
    
    # 取消来自远程服务器的chao用户对数据库db1的所有表的所有权限
    
    revoke all on db1.* from 'chao'@"%";  
    
    取消来自远程服务器的chao用户所有数据库的所有的表的权限
    revoke all privileges on *.* from 'chao'@'%';
    
    

    3. 数据备份与还原

    备份:

    mysqldump -uroot -p -B -d 库 >路径+文件名称.sql
    
    -B :会记录库名,还原的时候会自动创建这个库。
    
    

    还原:

    mysql -uroot -p < 路径+文件名称.sql
    
    

    4. mysql锁

    Innodb默认加行锁, MyISAM 默认表锁。

    # 加表锁:
    显示加锁:
    	共享读锁:lock table tableName read;
    	独占写锁:lock table tableName write;
    
        同时加多锁:lock table t1 write,t2 read;
    	批量解锁:unlock tables;
    
    
    # 行级锁:
    排它锁:
    	select * from 表名 where 条件 for update;
    
    

    查看死锁

    第一种:
    	1.查询是否锁表
        show OPEN TABLES where In_use > 0;
    	2.查询进程(如果您有SUPER权限,您可以看到所有线程。否则,只能看到自己的线程)
        show processlist
    	3.杀死进程id(就是上面命令的id列)
        kill id
    第二种:
    	1.查看下在锁的事务 
        SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
    	2.杀死进程id(就是上面命令的trx_mysql_thread_id列)
    	   kill 线程ID
    例子:
      查出死锁进程:SHOW PROCESSLIST
      杀掉进程     KILL 420821;
    其它关于查看死锁的命令:
      1:查看当前的事务
        SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
      2:查看当前锁定的事务
        SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
      3:查看当前等锁的事务
        SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
    
    

    5. 事务

    逻辑上是一组sql语句操作,组成这组操作的各个sql语句,执行时要么全部成功,要么全部失败。

    5.1 事务属性

    事务是由一组SQL语句组成的逻辑处理单元,事务具有ACID属性。
    
    1. 原子性(Atomicity):事务是一个原子操作单元。在当时原子是不可分割的最小元素,其对数据的修改,要么全部成功,要么全部都不成功。
    2. 一致性(Consistent):事务开始到结束的时间段内,数据都必须保持一致状态。
    3. 隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的"独立"环境执行。
    4. 持久性(Durable):事务完成后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。
    
    

    5.2 事务常见问题

    1.更新丢失(Lost Update)
      原因:当多个事务选择同一行操作,并且都是基于最初选定的值,由于每个事务都不知道其他事务的存在,就会发生更新覆盖的问题。类比github提交冲突。
    
    2.脏读(Dirty Reads)
      原因:事务A读取了事务B已经修改但尚未提交的数据。若事务B回滚数据,事务A的数据存在不一致性的问题。
    
    3.不可重复读(Non-Repeatable Reads)
      原因:事务A第一次读取最初数据,第二次读取事务B已经提交的修改或删除数据。导致两次读取数据不一致。不符合事务的隔离性。
    
    4.幻读(Phantom Reads)
       原因:事务A根据相同条件第二次查询到事务B提交的新增数据,两次数据结果集不一致。不符合事务的隔离性。
    
    

    5.3 操作

    开启事物:start transaction; / begin;
    commit; 提交保存
    rollback; 回滚事务
    
    在事务中加锁,如果一直没有commit,这把锁一直会存在。
    
    
  • 相关阅读:
    Java基础之集合框架(Collection接口和List接口)
    Management
    .NET实现多个不同有效时间Session方案思考
    C#操作MySql数据库帮助类(Dapper,T-Sql)
    MVC控制器传递多个实体类集合到视图的方案总结
    高德js API根据出行方式和出现策略由起始点经纬度实现路线规划
    c#QQ邮件编程学习(收发邮件)
    自定义tt文本模板实现MySql指数据库中生成实体类
    Socket客户端
    Socket服务端
  • 原文地址:https://www.cnblogs.com/yzm1017/p/11478524.html
Copyright © 2011-2022 走看看