Sql查询优化--索引设计与sql优化(包含慢查询定位+explain解释计划+左匹配原则+索引失效)

        本文介绍了数据库查询的索引优化方法,依次介绍了慢查询语句定位方法、索引设计与sql语句优化方法,并介绍了左匹配原则和索引失效的场景,最后介绍了explain执行计划要怎么看以调整检验索引设计是否生效和效率情况,创新介绍了如何以业务板块及大表为切入点,系统性设计索引,用最少的索引覆盖最多的查询语句。在实践中将整个业务板块的多个大表查询和复杂查询sql优化从40s以上优化到3s以内,保障系统正常运行。

优化前:43秒

优化后:4秒

一、慢查询定位

在排除前端请求超时时长设置和nginx负载以后,可以慢查询定位找到查询耗时长的sql语句。

1、Oracle 慢查询耗时定位

select *

 from (select sa.SQL_TEXT "执行 SQL",

        sa.EXECUTIONS "执行次数",

        round(sa.ELAPSED_TIME / 1000000, 2) "总执行时间",

        round(sa.ELAPSED_TIME / 1000000 / sa.EXECUTIONS, 2) "平均执行时间",

        sa.COMMAND_TYPE,

        sa.PARSING_USER_ID "用户 ID",

        u.username "用户名",

        sa.HASH_VALUE

     from v$sqlarea sa

     left join all_users u

      on sa.PARSING_USER_ID = u.user_id

     where sa.EXECUTIONS > 0

     order by (sa.ELAPSED_TIME / sa.EXECUTIONS) desc)

 where rownum <= 50;

2、mysql 慢查询耗时定位

查询是否开启慢查询日志:show variables like ‘slow_query_log’;

  • 开启慢查询sql:set global slow_query_log = 1/on;
  • 关闭慢查询sql:set global slow_query_log = 0/off;

二、索引设计方法

1、单索引和联合索引

      联合索引的优先级大于普通索引。索引相当于路线,即使一张表有多个索引,一个查询(子查询)只能走一个索引,走了其中一个索引就相当于走了一条路,不会同时走多个索引。

2、最大区分度

根据业务,where、group by、order等最常用到的关键词,能最大程度区分数据,记录中最具代表性质的字段。如status之类的字段则不便于建立索引。

3、遵循左匹配原则

索引index(a,b,c);   

查询语句where b=1 and c =3【不走索引】

查询语句where a=1 and c =3【走部分索引,索引存在中断】

查询语句where b=1 and a=3【走部分索引,左匹配原则和索引列的顺序有关,和查询列的顺序无关,因sql有查询优化器,可以调整sql执行方法】

查询语句where b=1 and a=3 and c=9 【走索引】

4、根据业务设计(**实战重点**)

(1)一张表的索引并非越多越好,索引过多对空间造成浪费,在新增和删除、修改时浪费效率。一张表建议不超过5个索引。

(2)首先根据一块业务找到涉及到的表,找到关联left join的关键字。

(3)一块业务流程中的用到的所有复杂查询语句、常用查询语句、大表查询语句、慢查询语句,提取出来分析(也可用慢查询分析)。

(4)关注where、order、group by、select、left join、实际数据记录重要性质区分的字段。各个sql语句的字段按字典序进行排序,关注每个sql语句涉及字段的交集。

(5)以交集字段建立联合索引,实现尽可能少的建立索引,尽可能多的sql语句能走索引查询。

Eg:

Sql_1 语句:select a from table_1 where a=1 and b=1 and c=2 and d=3;

Sql_2 语句:select a from table_1 where b=1 and c=1;

Sql_3 语句:select a from table_1 group by c,d;

此时3个语句的关键字中此时可以依据顺序建立索引index(c,a,b),注意索引顺序,三个语句都可以走联合索引。

其他复杂子查询或连接查询也依次法分析。

(6)根据Sql优化方法和explain分析,调整索引(见目录三、六)

三、Sql优化方法

1、小表驱动大表

含有子查询的语句,in 用于子查询范围小于外查询,exist则反过来

2、union all 代替 union

减少过滤

3、Join代替子查询

减少回表

4、Where条件代替having

5、Select 字段值 代替 select *

四、左匹配原则

创建联合索引时,首先会对最左边字段排序,也就是第一个字段,然后再在保证第一个字段有序的情况下,再排序第二个字段,以此类推。

索引index(a,b,c);   

查询语句where b=1 and c =3【不走索引】

查询语句where a=1 and c =3【走部分索引,索引存在中断】

查询语句where b=1 and a=3【走部分索引,左匹配原则和索引列的顺序有关,和查询列的顺序无关,因sql有查询优化器,可以调整sql执行方法】

查询语句where b=1 and a=3 and c=9 【走索引】

五、索引失效

1、索引列存在函数运算或类型转换

>、<、between中断索引,只能匹配部分

2、like ‘%dkla0’        %出现在最左端会失效

3、Or两边有其中一边没有走索引l

4、不满足左匹配原则

六、EXPLAIN解释计划执行含义

1、Mysql中

关注type列:

system > const > eq_ref > ref > range > index > all

2、Oracle中

关注operation列:

index unique scan>index range scan>index skip scan>index fast full scan>index full scan>table access ful

mysql索引【type列】

oracle索引【operation列】

system

只有一条记录

index unique scan

主键扫描

const

主键+唯一【返回一行】

index range scan

索引范围扫描

eq ref

唯一索引

index skip scan

索引跳跃扫描

ref

联合索引

index fast full scan

索引快速扫描

range

主键或者索引,进行范围查询

index full scan

索引全扫

index

遍历索引树,索引全部数据

table access ful

全表查询

all

全表查询

索引跳跃扫描:不满足左前缀匹配原则时,sql优化器

索引快速扫描:无序

索引全扫:有序(order by索引)

七、索引操作语句

1、新增

alter table table_name ADD INDEX [index_name] (index_col_name,...)

2、删除

DROP INDEX index_name ON tbl_name;

八、效果

其他同业务查询的相关语句也缩减到3s以内

优化前:43秒

优化后:4秒

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值