当前位置: 首页 > news >正文

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_VALUEfrom v$sqlarea saleft join all_users uon sa.PARSING_USER_ID = u.user_idwhere sa.EXECUTIONS > 0order 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秒

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • [pytorch] --- pytorch基础之tensorboard使用
  • Vue 登录状态判断与跳转指南
  • 一.海量数据实时分析-Doris入门和安装
  • JMeter之上传文件同时带有参数
  • Python计算机视觉四章-照相机模型与增强现实
  • Spring Cloud全解析:网关之GateWay过滤器
  • RASA使用长文记录以及一些bug整理
  • 鸿蒙启动框架配置文件(StartUpTask)
  • 学习记录:js算法(二十一):字符串的排列、替换后的最长重复字符
  • YOLOv9改进策略【模型轻量化】| MoblieNetV3:基于搜索技术和新颖架构设计的轻量型网络模型
  • 前端内存泄露案例与解决方案
  • Ubuntu 安装个人热点
  • 字符集介绍
  • 八、2 DMA数据转运 DMA函数介绍
  • 使用 streamlink 把 m3u8 转为 mp4
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • Consul Config 使用Git做版本控制的实现
  • EOS是什么
  • iOS帅气加载动画、通知视图、红包助手、引导页、导航栏、朋友圈、小游戏等效果源码...
  • Java比较器对数组,集合排序
  • miaov-React 最佳入门
  • Python - 闭包Closure
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • sessionStorage和localStorage
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 理解在java “”i=i++;”所发生的事情
  • 区块链共识机制优缺点对比都是什么
  • 吐槽Javascript系列二:数组中的splice和slice方法
  • 小李飞刀:SQL题目刷起来!
  • 一个完整Java Web项目背后的密码
  • 译米田引理
  • 终端用户监控:真实用户监控还是模拟监控?
  • Android开发者必备:推荐一款助力开发的开源APP
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • (4.10~4.16)
  • (AngularJS)Angular 控制器之间通信初探
  • (创新)基于VMD-CNN-BiLSTM的电力负荷预测—代码+数据
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (转)创业家杂志:UCWEB天使第一步
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • .naturalWidth 和naturalHeight属性,
  • .NET delegate 委托 、 Event 事件,接口回调
  • .NET Micro Framework初体验
  • .Net Web项目创建比较不错的参考文章
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .net6 webapi log4net完整配置使用流程
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • /var/spool/postfix/maildrop 下有大量文件
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504