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

2、索引种类

  • 普通索引:仅加速查询
  • 唯一索引:加速查询 + 列值唯一(可以有null)
  • 主键索引:加速查询 + 列值唯一 + 表中只有一个(不可以有null)
  • 组合索引:多列值组成一个索引,
                  专门用于组合搜索,其效率大于索引合并
  • 全文索引:对文本的内容进行分词,进行搜索 

索引合并,使用多个单列索引组合搜索
覆盖索引,select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖

3、相关命令

    - 查看表结构
        desc 表名

    - 查看生成表的SQL
        show create table 表名

    - 查看索引
        show index from  表名

    - 查看执行时间
        set profiling = 1;
        SQL...
        show profiles;

4、使用索引和不使用索引

    由于索引是专门用于加速搜索而生,所以加上索引之后,查询效率会快到飞起来。

    # 有索引
    mysql> select * from tb1 where name = 'wupeiqi-888';
    +-----+-------------+---------------------+----------------------------------+---------------------+
    | nid | name        | email               | radom                            | ctime               |
    +-----+-------------+---------------------+----------------------------------+---------------------+
    | 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
    +-----+-------------+---------------------+----------------------------------+---------------------+
    1 row in set (0.00 sec)

    # 无索引
    mysql> select * from tb1 where email = 'wupeiqi888@live.com';
    +-----+-------------+---------------------+----------------------------------+---------------------+
    | nid | name        | email               | radom                            | ctime               |
    +-----+-------------+---------------------+----------------------------------+---------------------+
    | 889 | wupeiqi-888 | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
    +-----+-------------+---------------------+----------------------------------+---------------------+
    1 row in set (1.23 sec)

5、正确使用索引

数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。
即使建立索引,索引也不会生效:

        - 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;

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

6、其他注意事项

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

7、limit分页

无论是否有索引,limit分页是一个值得关注的问题

每页显示10条:
当前 118 120125

倒序:
            大      小
            980    970  7 6  6 5  54  43  32

21 19 98     
下一页:

    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;
View Code

相关文章:

  • 2021-11-24
  • 2021-08-26
  • 2022-12-23
  • 2021-10-15
  • 2021-05-27
  • 2021-07-25
  • 2021-06-06
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-06-18
  • 2022-01-30
  • 2021-06-13
  • 2022-12-23
相关资源
相似解决方案