加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python-day44_MySQL数据库4-索引

发布时间:2020-12-20 12:59:05 所属栏目:Python 来源:网络整理
导读:1,索引 作用:约束,加速查找 分类: 主键索引:加速查找+不能为空+不能重复 普通索引:加速查找 唯一索引:加速查找+不能重复 联合索引(多列):联合主键索引,联合唯一索引,联合普通索引 加速查找: SELECT * FROM tb WHERE name=‘dksl‘ #从头到尾查找

1,索引

  作用:约束,加速查找

  分类:

    主键索引:加速查找+不能为空+不能重复

    普通索引:加速查找

    唯一索引:加速查找+不能重复

    联合索引(多列):联合主键索引,联合唯一索引,联合普通索引

  加速查找:

    SELECT * FROM tb WHERE name=‘dksl‘  #从头到尾查找,慢

    SELECT * FROM tb WHERE id=999  #主键查找快

  无索引:从前到后依次查找
  索引:
    id       创建额外文件(某种格式存储)
    name    创建额外文件(某种格式存储)
    email    创建额外文件(某种格式存储) create index ix_name on userinfo3(email);
    name email 创建额外文件(某种格式存储)

2,索引种类(某种格式存储):
    hash索引:
      单值快
      指定查找范围无法用于加速
    btree索引:?
      二叉树

  建立索引:
    - a. 会生成额外的文件保存特殊的数据结构
    - b. 查询快;但插入更新删除慢
    - c. 查找时需命中索引才能加速

  主键索引:
    本身就能加速
  普通索引:
    - create index 索引名称 on 表名(列名,)
    - drop index 索引名称 on 表名
  唯一索引:
    - create unique index 索引名称 on 表名(列名)
    - drop unique index 索引名称 on 表名

  组合索引(最左前缀匹配,即WHERE查找时,最左列名必须存在才会命中索引):
    - create index 索引名称 on 表名(列名1,列名2)  #列名1是最左前缀
    - drop index 索引名称 on 表名

?  例:

    - create index ix_name_email on userinfo3(name,email)
    - 最左前缀匹配
      select * from userinfo3 where name=‘alex‘;
      select * from userinfo3 where name=‘alex‘ and email=‘asdf‘;

      select * from userinfo3 where email=‘[email?protected]‘;

    组合索引效率 > 索引合并
    组合索引
      - (name,email)   #按这个建一个索引,以下2个才能命中索引
      select * from userinfo3 where name=‘alex‘ and email=‘asdf‘;
      select * from userinfo3 where name=‘alex‘;
    索引合并:
      - name 建一个索引
      - email 建一个索引   #以下4个都能命中索引
        select * from userinfo3 where name=‘alex‘ and email=‘asdf‘;
        select * from userinfo3 where name=‘alex‘;
        select * from userinfo3 where email=‘alex‘;

?        select * from userinfo3 where email=‘asdf‘?and name=‘alex‘;

?    覆盖索引: - 在索引文件中直接获取数据,不需要再查找数据库本身

    索引合并:  - 把多个单列索引合并使用

?3,为频繁查找的列创建索引

  以下操作会变慢

  - like ‘%xx‘
    select * from tb1 where email like ‘%cn‘;


  - 使用函数
    select * from tb1 where reverse(email) = ‘wupeiqi‘;

  - or
    select * from tb1 where nid = 1 or name = ‘[email?protected]‘;

    特别的:当or条件中有未建立索引的列才失效,以下会走索引
    select * from tb1 where nid = 1 or name = ‘seven‘;
    select * from tb1 where nid = 1 or name = ‘[email?protected]‘ and email = ‘alex‘

  - 类型不一致
    如果列是字符串类型,传入条件是必须用引号引起来,不然...
    select * from tb1 where email = 999;

  - !=
    select * from tb1 where email != ‘alex‘

  特别的:如果是主键,则还是会走索引
    select * from tb1 where nid != 123
    - >
    select * from tb1 where email > ‘alex‘

  特别的:如果是主键或索引是整数类型,则还是会走索引
    select * from tb1 where nid > 123
    select * from tb1 where num > 123

  - order by
    select name from tb1 order by email desc;

  当根据索引排序时候,选择的映射如果不是索引,则不走索引
  特别的:如果对主键排序,则还是走索引:
    select * from tb1 order by nid desc;

  - 组合索引最左前缀
    如果创建的组合索引为:(name,email)
    name and email -- 使用索引
    name -- 使用索引
    email -- 不使用索引

?

4,时间

  执行计划:让mysql预估执行的操作类型(一般正确)
    效率对比:
    all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
  id,email假设做了索引

  慢:
    select * from userinfo3 where name=‘alex‘

    explain select * from userinfo3 where name=‘alex‘   #运行执行计划
    type: ALL(代表全表扫描)
    select * from userinfo3 limit 1;
  快:
    select * from userinfo3 where email=‘alex‘
    type: ref(代表走索引)

?

5,DBA工作

  慢日志
    - 执行时间 > 10秒,记录到慢日志中
    - 未命中索引
    - 日志文件路径

  配置慢日志:
  - 基于内存
    show variables like ‘%query%‘
    show variables like ‘%queries%‘
    set global 变量名 = 值 #修改当前配置

    slow_query_log = OFF 是否开启慢日志记录
    long_query_time = 2 时间限制,超过此时间,则记录
    slow_query_log_file = /usr/slow.log 日志文件
    log_queries_not_using_indexes = OFF 未使用索引的搜索是否记录
  - 基于配置文件
    mysqld --defaults-file=‘E:wupeiqimysql-5.7.16-winx64mysql-5.7.16-winx64my-default.ini‘

    my.conf内容:
    slow_query_log = ON
    slow_query_log_file = D:/....

    注意:修改配置文件之后,需要重启服务来加载它

?

?6,分页

  查找会从数据库开头开始找到开始行,再从指定行开始输出指定行数   a. select * from userinfo3 limit 20,10;   b.解决方案     - 超过的页数不让看     - 索引表中扫:       select * from userinfo3 where id in(select id from userinfo3 limit 200000,10)     - 方案:     记录当前页最大或最小ID     1. 页面只有上一页,下一页       # max_id       # min_id       下一页:       select * from userinfo3 where id > max_id limit 10;       上一页:       select * from userinfo3 where id < min_id order by id desc limit 10;     2. 上一页 192 193 [196] 197 198 199 下一页       select * from userinfo3 where id in (       select id from (select id from userinfo3 where id > max_id limit 30) as N order by N.id desc limit 10       )??order by id limit 10;     c. *****为什么不用between*****:       id不连续,所以无法直接使用id范围进行查找

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读