zoukankan      html  css  js  c++  java
  • MySQL/索引

    1.索引:

    索引是表的目录,在查找内容之前可以先在目录中查找索引位置,此次快速定位查询数据。对于索引,会保存在额外的文件中。

    1.1 MySQL中常见索引有:

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

                普通索引:加速查找

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

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

    1.2 作用:约束、加速查找

    1.3 创建普通索引:

    create index 索引名称 on userinfo3(email);
    

     删除索引: 

    drop index_name on userinfo3;
    

    查看索引: 

    show index from userinfo3;
    

    注意:对于创建索引是如果是blob和text类型,必须指定length。

            create index ix_extra on userinfo3(extra(32));

    1.4索引种类(某种格式存储):

    hash索引:单值查找快 查找范围

    btree索引:二叉树

     结果:快

    2.建立索引:

    a:额外的文件保存特殊的数据结构

    b:查询快,插入更新删除慢

    c:命中索引:如你创建了一个email的索引,要查找的时候需要根据命名的索引进行查找,这样查找速度快

    select *from userinfo3 where email = 'asdf';  查询速度快
    select *from userinfo3 where email like 'asdf'; 查询速度慢

     主键索引:

     普通索引:

    create index 索引名称 on 表名(列名)
    drop index 索引名称 on 表名   删除索引 

    唯一索引:

    create unique index 索引名称 on 表名(列名)
    drop unique index 索引名称 on表名

    组合索引(最左前缀匹配):

    create unique index 索引名称 on 表名(列名,列名)
     drop unique index 索引名称 on 表名
    create unique 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='alex@qq.com'; 不是前缀匹配
                      
    组合索引(多列):多列值组成一个索引,专门用于组合搜索效率大于索引合并
                                (name,email)
                                          select *from userinfo3 where name ='alex'; 
                                          select *from userinfo3 where name='alex' and email='asdf';
        
     索引合并(单列):把多个单列索引合并使用
                                 name
                                 email
                                      select *from userinfo3 where name=“alex”and email='asdf';
                                      select *from userinfo3 where name=‘alex’;
                                      select *from userinfo3 where email=‘alex’;
    索引覆盖:在索引文件中直接获取数据
    全文索引:对文本的内容进行分词,进行搜索

    3. 频繁查找的列创建索引:

    - 创建索引

    - 命中索引 *****联合使用

    即时建立索引,索引也不会生效:

    - like '%xx'
        select * from tb1 where name like '%cn';
    - 使用函数
        select * from tb1 where reverse(name) = 'wupeiqi';
    - or
        select * from tb1 where nid = 1 or email = 'seven@live.com';
        特别的:当or条件中有未建立索引的列才失效,以下会走索引
                select * from tb1 where nid = 1 or name = 'seven';
                select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'alex'
    - 类型不一致
        如果列是字符串类型,传入条件是必须用引号引起来,不然...
        select * from tb1 where name = 999;
    - !=
        select * from tb1 where name != 'alex'
        特别的:如果是主键,则还是会走索引
            select * from tb1 where nid != 123
    - >
        select * from tb1 where name > 'alex'
        特别的:如果是主键或索引是整数类型,则还是会走索引
            select * from tb1 where nid > 123
            select * from tb1 where num > 123
    - order by
        select email from tb1 order by name desc;
        当根据索引排序时候,选择的映射如果不是索引,则不走索引
        特别的:如果对主键排序,则还是走索引:
                select * from tb1 order by nid desc;
    View Code

    其他注意事项:  

    - 避免使用select *
    - count(1)或count(列) 代替 count(*)
    - 创建表时尽量使 char 代替 varchar
    - 表的字段顺序固定长度的字段优先
    - 组合索引代替多个单列索引(经常使用多个条件查询时)
    - 尽量使用短索引
    - 使用连接(JOIN)来代替子查询(Sub-Queries)
    - 连表时注意条件类型需一致
    - 索引散列值(重复少)不适合建索引,例:性别不适合
    其他注意事项

    4.执行计划

     explain+查询sql  -用于显示sql执行信息参数,根据参考信息可以进行sql优化

    mysql> explain select *from useru;
    
    +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra 
    +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
    |  1 | SIMPLE      | useru | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1835575 |   100.00 | NULL  
    +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
    1 row in set, 1 warning (0.01 sec)
    

    all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const

    慢:
            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  const(走索引)
    View Code
    mysql> explain select *from useru where uname="alex122";
    
    +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
    |  1 | SIMPLE      | useru | NULL       | ref  | inss          | inss | 766     | const |    1 |   100.00 | NULL  |
    +----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------+
    1 row in set, 1 warning (0.06 sec)
    mysql> explain select *from useru;
    
    +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
    | id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows    | filtered | Extra |
    +----+-------------+-------+------------+------+---------------+------+---------+------+---------+----------+-------+
    |  1 | SIMPLE      | useru | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 1835575 |   100.00 | NULL  |
    +----+-------------+-------+------------+------+---------------+------+---------+------+---  

    5.慢日志

    a:配置mysql自动记录慢日志
    slow_query_log = OFF                            是否开启慢日志记录
    long_query_time = 2                              时间限制,超过此时间,则记录
    slow_query_log_file = /usr/slow.log            日志文件
    log_queries_not_using_indexes = OFF         为使用索引的搜索是否记录

      注:查看当前配置信息:

          show variables like '%query%'

          修改当前配置:

          set global 变量名=值

     b:配置文件
     - 配置文件
    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.分页******

    - 索引表中扫:

    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;
    mysql> select *from useru where id >20000 limit 10;

    上一页:

    select * from userinfo3 where id < min_id order by id desc limit 10;
    mysql> select *from useru where id <20000 order by desc id limit 10;  

    2.上一页 192 193  [196]  197  198  199 下一页

    上一页:

    select * from tb1 where nid < (select nid from (select nid from tb1 where nid < 当前页最小值 order by nid desc limit 
            每页数据 *【页码-当前页】) A order by A.nid asc limit 1)  order by nid desc limit 10;
    
               select * from tb1 where nid < (select nid from (select nid from tb1 where nid < 970  order by nid desc limit 40) 
    A order by A.nid asc limit 1) order by nid desc limit 10;

    下一页:

             select * from tb1 where nid < (select nid from (select nid from tb1 where nid > 当前页最大值 order by nid asc limit 
    每页数据 *【当前页-页码】) A order by A.nid asc limit 1)  order by nid desc limit 10;
             
    select * from tb1 where nid < (select nid from (select nid from tb1 where nid > 980 order by nid asc limit 20) A order by 
    A.nid desc limit 1) order by nid desc limit 10;
  • 相关阅读:
    sql求两表的并集、交集、非交集、差集、结果集排序
    c# 为什么要使用Array、ArrayList、List?
    C# 实例化的执行顺序(转)
    正则捕获url的?号传值
    mvc5中重命名项目的名称后,出现"找到多个与名为“Home”的控制器匹配的类型"
    微信开发资料
    windows下建立netcore控制台程序,然后传送到centos7下的docker容器里运行
    error MSB3552: Resource file "**/*.resx" cannot be found. [/ConsoleApp1.csproj]
    c# 编译期常量const和运行时常量readonly
    c# 多线程之-- System.Threading Timer的使用
  • 原文地址:https://www.cnblogs.com/niejinmei/p/7002474.html
Copyright © 2011-2022 走看看