Mysql优化篇-索引优化与查询优化

1、索引失败案列

如果查询时没有使用索引,查询语句就会扫描表中所有记录,在数据量大的情况下,查询会很慢。
(1)全值匹配
(2)最佳左前缀法则
mysql可以为多个字段创建索引,一个索引可以包括16个字段,对于多列索引,过滤条件要使用索引必须按照索引建立时的孙旭,依次满足,一旦跳过某个字段,索引后面的字段都无法被使用,如果查询条件中没有使用这些字段中第一个字段时,多列或联合索引不会被使用
(3)主键插入顺序
对于一个使用InnoDB存储引擎的表来说,在没有显式的创建索引时,表中的数据实际上都是存储在聚簇索引的叶子节点的。而记录又是存储在数据页中的,数据页和记录又是按照记录主键值从小到大的顺序进行排序,所以如果插入的记录的主键值是依次增大的话,那每插满一个数据页就换到下一个数据页继续插,而如果插入的主键值忽大忽小的话(一般不让这种情况发生),就比较麻烦了,假设某个数据页存储的记录已经满了,它存储的主键值在1~100之间:
如果此时再插入一条主键值为 9 的记录,那么就会增加复杂
(4)计算、函数、类型转换(自动或手动)导致索引失效
例如:

EXPLAIN SELECT id, stuno, NAME FROM student WHERE SUBSTRING(NAME, 1,3)='abc';
/*索引失效
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | ALL  | NULL          | NULL | NULL    | NULL | 498858 |   100.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+

(5)类型转换导致索引失效

#5)类型转换导致索引失效
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE NAME = 123; 
/*没有使用索引:name是字符串类型,和int匹配要类型转换
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table   | partitions | type | possible_keys | key  | key_len | ref  | rows   | filtered | Extra       |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | student | NULL       | ALL  | idx_name      | NULL | NULL    | NULL | 498858 |    10.00 | Using where |
+----+-------------+---------+------------+------+---------------+------+---------+------+--------+----------+-------------+
*/
EXPLAIN SELECT SQL_NO_CACHE * FROM student WHERE NAME = '123'; 
/*使用了索引:
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+-------+
| id | select_type | table   | partitions | type | possible_keys | key      | key_len | ref   | rows | filtered | Extra |
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | student | NULL       | ref  | idx_name      | idx_name | 63      | const |    1 |   100.00 | NULL  |
+----+-------------+---------+------------+------+---------------+----------+---------+-------+------+----------+-------+
*/

(6) 范围条件右边的列索引失效
范围条件:含(<) (<=) (>) (>=)和between等的条件

  • 应用开发中范围查询,例如:金额查询,日期查询往往都是范围查询。应将查询条件放置where语句最后,建索引时也放在最后
    (创建的联合索引中,务必把范围涉及到的字段写在最后)
    (7)不等于(!= 或者<>)索引失效
    (8)不等于(!= 或者<>)索引失效,使用not like 也无法使用索引
    (9)like以通配符%开头索引失效
    如果匹配字符串的第一个字符为%,索引就不会起作用。只有%不在第一个位置,索引才会起作用。
    (10)OR前后存在非索引的列,索引失效。OR前后的两个条件中的列都是索引时,查询中才使用索引。
    (11)不同字符集进行比较需要进行转换,会造成索引失效
    统一使用utf8mb4兼容性更好,统一字符集可以避免由于字符集转换产生的乱码,不同字符集进行比较前需要进行转换会造成索引失效。建议数据库和表的字符集统一使用utf8mb4

2.关联查询优化(多表查询)

https://blog.csdn.net/IAMLSL/article/details/123103496?spm=1001.2014.3001.5501

posted @ 2022-08-05 17:31  spiderMan1-1  阅读(110)  评论(0编辑  收藏  举报