MySQL---正确使用索引、limit分页、执行计划、慢日志查询

正确使用索引

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

 1 - like ‘%xx‘
 2     select * from tb1 where name like ‘%cn‘;
 3 - 使用函数
 4     select * from tb1 where reverse(name) = ‘wupeiqi‘;
 5 - or
 6     select * from tb1 where nid = 1 or email = ‘[email protected]‘;
 7     特别的:当or条件中有未建立索引的列才失效,以下会走索引
 8             select * from tb1 where nid = 1 or name = ‘seven‘;
 9             select * from tb1 where nid = 1 or email = ‘[email protected]‘ and name = ‘alex‘
10 - 类型不一致
11     如果列是字符串类型,传入条件是必须用引号引起来,不然...
12     select * from tb1 where name = 999;
13 - !=
14     select * from tb1 where name != ‘alex‘
15     特别的:如果是主键,则还是会走索引
16         select * from tb1 where nid != 123
17 - >
18     select * from tb1 where name > ‘alex‘
19     特别的:如果是主键或索引是整数类型,则还是会走索引
20         select * from tb1 where nid > 123
21         select * from tb1 where num > 123
22 - order by
23     select email from tb1 order by name desc;
24     当根据索引排序时候,选择的映射如果不是索引,则不走索引
25     特别的:如果对主键排序,则还是走索引:
26         select * from tb1 order by nid desc;
27
28 - 组合索引最左前缀
29     如果组合索引为:(name,email)
30     name and email       -- 使用索引
31     name                 -- 使用索引
32     email                -- 不使用索引

其他注意事项

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

limit分页

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

 1 每页显示10条:
 2 当前 118 120, 125
 3
 4 倒序:
 5             大      小
 6    970  7 6  6 5  54  43  32
 7 19 98
 8 下一页:
 9
10     select
11         *
12     from
13         tb1
14     where
15         nid < (select nid from (select nid from tb1 where nid < 当前页最小值 order by nid desc limit 每页数据 *【页码-当前页】) A order by A.nid asc limit 1)
16     order by
17         nid desc
18     limit 10;
19
20
21
22     select
23         *
24     from
25         tb1
26     where
27         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)
28     order by
29         nid desc
30     limit 10;
31
32
33 上一页:
34
35     select
36         *
37     from
38         tb1
39     where
40         nid < (select nid from (select nid from tb1 where nid > 当前页最大值 order by nid asc limit 每页数据 *【当前页-页码】) A order by A.nid asc limit 1)
41     order by
42         nid desc
43     limit 10;
44
45
46     select
47         *
48     from
49         tb1
50     where
51         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)
52     order by
53         nid desc
54     limit 10;

执行计划

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

1 mysql> explain select * from tb2;
2 +----+-------------+-------+------+---------------+------+---------+------+------+-------+
3 | id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra |
4 +----+-------------+-------+------+---------------+------+---------+------+------+-------+
5 |  1 | SIMPLE      | tb2   | ALL  | NULL          | NULL | NULL    | NULL |    2 | NULL  |
6 +----+-------------+-------+------+---------------+------+---------+------+------+-------+
7 1 row in set (0.00 sec)

 1 id
 2         查询顺序标识
 3             如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
 4             +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
 5             | id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
 6             +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
 7             |  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |    9 | NULL        |
 8             |  2 | DERIVED     | tb1        | range | PRIMARY       | PRIMARY | 8       | NULL |    9 | Using where |
 9             +----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
10         特别的:如果使用union连接气值可能为null
11
12
13     select_type
14         查询类型
15             SIMPLE          简单查询
16             PRIMARY         最外层查询
17             SUBQUERY        映射为子查询
18             DERIVED         子查询
19             UNION           联合
20             UNION RESULT    使用联合的结果
21             ...
22     table
23         正在访问的表名
24
25
26     type
27         查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
28             ALL             全表扫描,对于数据表从头到尾找一遍
29                             select * from tb1;
30                             特别的:如果有limit限制,则找到之后就不在继续向下扫描
31                                    select * from tb1 where email = ‘[email protected]‘
32                                    select * from tb1 where email = ‘[email protected]‘ limit 1;
33                                    虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。
34
35             INDEX           全索引扫描,对索引从头到尾找一遍
36                             select nid from tb1;
37
38             RANGE          对索引列进行范围查找
39                             select *  from tb1 where name < ‘alex‘;
40                             PS:
41                                 between and
42                                 in
43                                 >   >=  <   <=  操作
44                                 注意:!= 和 > 符号
45
46
47             INDEX_MERGE     合并索引,使用多个单列索引搜索
48                             select *  from tb1 where name = ‘alex‘ or nid in (11,22,33);
49
50             REF             根据索引查找一个或多个值
51                             select *  from tb1 where name = ‘seven‘;
52
53             EQ_REF          连接时使用primary key 或 unique类型
54                             select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
55
56
57
58             CONST           常量
59                             表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
60                             select nid from tb1 where nid = 2 ;
61
62             SYSTEM          系统
63                             表仅有一行(=系统表)。这是const联接类型的一个特例。
64                             select * from (select nid from tb1 where nid = 1) as A;
65     possible_keys
66         可能使用的索引
67
68     key
69         真实使用的
70
71     key_len
72         MySQL中使用索引字节长度
73
74     rows
75         mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值
76
77     extra
78         该列包含MySQL解决查询的详细信息
79         “Using index”
80             此值表示mysql将使用覆盖索引,以避免访问表。不要把覆盖索引和index访问类型弄混了。
81         “Using where”
82             这意味着mysql服务器将在存储引擎检索行后再进行过滤,许多where条件里涉及索引中的列,当(并且如果)它读取索引时,就能被存储引擎检验,因此不是所有带where子句的查询都会显示“Using where”。有时“Using where”的出现就是一个暗示:查询可受益于不同的索引。
83         “Using temporary”
84             这意味着mysql在对查询结果排序时会使用一个临时表。
85         “Using filesort”
86             这意味着mysql会对结果使用一个外部索引排序,而不是按索引次序从表里读取行。mysql有两种文件排序算法,这两种排序方式都可以在内存或者磁盘上完成,explain不会告诉你mysql将使用哪一种文件排序,也不会告诉你排序会在内存里还是磁盘上完成。
87         “Range checked for each record(index map: N)”
88             这个意味着没有好用的索引,新的索引将在联接的每一行上重新估算,N是显示在possible_keys列中索引的位图,并且是冗余的。

详细

慢日志查询

a、配置MySQL自动记录慢日志

1 slow_query_log = OFF                            是否开启慢日志记录
2 long_query_time = 2                              时间限制,超过此时间,则记录
3 slow_query_log_file = /usr/slow.log        日志文件
4 log_queries_not_using_indexes = OFF     为使用索引的搜索是否记录

注:查看当前配置信息:
       show variables like ‘%query%‘
     修改当前配置:
    set global 变量名 = 值

b、查看MySQL慢日志

mysqldumpslow -s at -a  /usr/local/var/mysql/MacBook-Pro-3-slow.log

 1 """
 2 --verbose    版本
 3 --debug      调试
 4 --help       帮助
 5
 6 -v           版本
 7 -d           调试模式
 8 -s ORDER     排序方式
 9              what to sort by (al, at, ar, c, l, r, t), ‘at‘ is default
10               al: average lock time
11               ar: average rows sent
12               at: average query time
13                c: count
14                l: lock time
15                r: rows sent
16                t: query time
17 -r           反转顺序,默认文件倒序拍。reverse the sort order (largest last instead of first)
18 -t NUM       显示前N条just show the top n queries
19 -a           不要将SQL中数字转换成N,字符串转换成S。don‘t abstract all numbers to N and strings to ‘S‘
20 -n NUM       abstract numbers with at least n digits within names
21 -g PATTERN   正则匹配;grep: only consider stmts that include this string
22 -h HOSTNAME  mysql机器名或者IP;hostname of db server for *-slow.log filename (can be wildcard),
23              default is ‘*‘, i.e. match all
24 -i NAME      name of server instance (if using mysql.server startup script)
25 -l           总时间中不减去锁定时间;don‘t subtract lock time from total time
26 """

原文地址:https://www.cnblogs.com/horror/p/9535648.html

时间: 2024-08-28 18:51:42

MySQL---正确使用索引、limit分页、执行计划、慢日志查询的相关文章

MySQL 索引管理与执行计划

原文:MySQL 索引管理与执行计划 1.1 索引的介绍 索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息.如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信息. 索引的一个主要目的就是加快检索表中数据的方法,亦即能协助信息搜索者尽快的找到符合限制条件的记录ID的辅助数据结构. 1.1.1 唯一索引 唯一索引是不允许其中任何两行具有相同索引值的索引.当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一

MySQL索引管理及执行计划

第1章 索引介绍: 索引是对数据库表中一列或者多了的值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息,如果想按特定职员的姓名来查找,则与他在表中搜索所有的行相比,索引有助于更快的获取信息 索引的一个主要目的就是加快检索表中的数据的方法,既能协助信息搜索者尽快找到符合限制条件的记录ID的辅助数据结构 1.1 索引的类型介绍: btree:B+树索引    最为常用 hash:hash索引 fulltest:全文索引 rtree:r数索引 第2章 索引管理 2.1 B树索引的分类: 主

Mysql索引、explain执行计划

1.索引的使用场景 哪些情况使用索引: 1.主键自动建立唯一索引 2.频繁作为查询条件的字段应该创建索引 where 3.多表关联查询中,关联字段应该创建索引on两边都要创建索引 select * from user left join order on user.id = order.userid 4.查询中排序的字段,应该创建索引B + tree 有顺序 5.覆盖索引 好处是?不需要回表组合索引 user表 组合索引(name,age) select * from user -------

初步理解MySQL(5.6)的执行计划

声明:以下均来自于MySQL英文手册5.6. 1.MySQL所有的join都是使用 nest-loop join 算法(嵌套循环算法). 2.对于一组joins,MySQL的join算法会从第一个表读取一行,然后一直往后逐个表找匹配行,如果某一行能够从第一个表开始,之后每个表都能找到匹配的行,则输出该"大行":然后原路返回到之前的表直到能找到一张中包含匹配行的表为止,然后继续向后面的每个表找匹配的行. 3.MySQL中索引的使用会被索引的cardinality所影响,cardinali

MySQL——通过EXPLAIN分析SQL的执行计划

在MySQL中,我们可以通过EXPLAIN命令获取MySQL如何执行SELECT语句的信息,包括在SELECT语句执行过程中表如何连接和连接的顺序. 下面分别对EXPLAIN命令结果的每一列进行说明: select_type:表示SELECT的类型,常见的取值有: 类型 说明 SIMPLE 简单表,不使用表连接或子查询 PRIMARY 主查询,即外层的查询 UNION UNION中的第二个或者后面的查询语句 SUBQUERY 子查询中的第一个 table:输出结果集的表(表别名) type:表示

Mongodb索引和执行计划 hint 慢查询

查询索引 索引存放在system.indexes集合中 > show tables address data person system.indexes 默认会为所有的ID建上索引 而且无法删除 > db.system.indexes.find() { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "

MySQL学习【第七篇索引管理及执行计划】

一.索引介绍 1.什么是索引? 索引由如字典,目的就是为了更快寻找到要找的内容. 令搜索查询的数据更有目的性,从而提高数据检索的能力 2.索引类型介绍 1.BTREE: B+树索引 2.HASH: HASH 索引 3.FULLTEXT: 全文索引 4.RTREE:R树索引 一般人不用懂上面4种算法!!!!!讲起来太特么麻烦了!!!! 简单介绍下hash索引一般就是查url的,网址一般都很长,查询则会变得十分麻烦,而hash则是令这一段url定义为一个hash值指向url,查找就是查这个hash值

MySQL中怎么将LIMIT分页优化?

1.语法: *** limit [offset,] rows 一般是用于select语句中用以从结果集中拿出特定的一部分数据. offset是偏移量,表示我们现在需要的数据是跳过多少行数据之后的,可以忽略:rows表示我们现在要拿多少行数据. 2.栗子: ①select * from mytbl limit 10000,100 上边SQL语句表示从表mytbl中拿数据,跳过10000行之后,拿100行 ②select * from mytbl limit 0,100 表示从表mytbl拿数据,跳

于位图索引相关的执行计划

位图索引是oracle数据库里除B树索引之外的另外一种索引的类型,它主要用于数据仓库或者DSS系统.在数据仓库或DSS系统中,针对某些类型的sql,用位图索引比用B树索引要快很多,这主要是位图索引实现了快捷的按位运算的缘故. 位图索引的物理存储结构和普通B树索引的物理存储结构相似,也是按照被索引的键值列有序存储,只不过和索引键值一起存储的不再仅仅是索引键值所对应的rowid,而是变成了三部分的组合.这三部分分别为对应rowid的下限,对应rowid的上限和被压缩存储的位图(Bitmap Segm