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:\wupeiqi\mysql-5.7.16-winx64\mysql-5.7.16-winx64\my-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;

 

posted @ 2017-06-13 17:30  karina梅梅  阅读(181)  评论(0编辑  收藏  举报