首页 > 数据库 >SQL优化

SQL优化

时间:2024-08-05 16:43:27浏览次数:11  
标签:语句 sql 查询 索引 SQL 优化 id

1.千万级大表

第一优化你的sql和索引;
第二加缓存,memcached,redis;
第三以上都做了后,还是慢,就做主从复制或主主复制,读写分离,可以在应用层做,效率高,也可以
用三方工具,第三方工具推荐360的atlas,其它的要么效率不高,要么没人维护;
第四如果以上都做了还是慢,不要想着去做切分,mysql自带分区表,先试试这个,对你的应用是透明
的,无需更改代码,但是sql语句是需要针对分区表做优化的,sql条件中要带上分区条件的列,从而使查
询定位到少量的分区上,否则就会扫描全部分区,另外分区表还有一些坑,在这里就不多说了;
第五如果以上都做了,那就先做垂直拆分,其实就是根据你模块的耦合度,将一个大的系统分为多个小
的系统,也就是分布式系统;
第六才是水平切分,针对数据量大的表,这一步最麻烦,最能考验技术水平,要选择一个合理的
sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带
sharding key,将数据定位到限定的表上去查,而不是扫描全部的表;

实现一个查询,可以写出很多种查询语句,不同的语句,根据你选择的引擎、表中数据的分布情况、索引情况、数据库优化策略、查询中的锁策略等因素,
最终查询的效率相差很大;优化要从整体去考虑,有时你优化一条语句后,其它查询反而效率被降低了,所以要取一个平衡点;
即使精通mysql的话,除了纯技术面优化,还要根据业务面去优化sql语句,这样才能达到最优效果;

再说一下不同引擎的优化,myisam读的效果好,写的效率差,这和它数据存储格式,索引的指针和锁的策略有关的,它的数据是顺序存储的(innodb数据存储方式是聚簇索引),他的索引btree上的节点是一个指向数据物理位置的指针,所以查找起来很快,(innodb索引节点存的则是数据的主键,所以需
要根据主键二次查找)
myisam锁是表锁,只有读读之间是并发的,写写之间和读写之间(读和插入之间是可以并发的,去设置concurrent_insert参数,定期执行表优化操作,更新操作就没有办法了)是
串行的,所以写起来慢,并且默认的写优先级比读优先级高,高到写操作来了后,可以马上插入到读操作前面去,如果批量写,会导致读请求饿死,所以要设置读写优先级或设置多少写操作后执行读操作的策略;myisam不要使用查询时间太长的sql,如果策略使用不当,也会导致写饿死,所以尽量去拆分查询效率低的sql

innodb一般都是行锁,这个一般指的是sql用到索引的时候,行锁是加在索引上的,不是加在数据记录上的,如果sql没有用到索引,仍然会锁定表,mysql的读写之间是可以并发的,普通的select是不需要锁的,当查询的记录遇到锁时,用的是一致性的非锁定快照读,也就是根据数据库隔离级别策略,会去读被锁定行的快照,其它更新或加锁读语句用的是当前读,读取原始行;因为普通读与写不冲突,所以innodb不会出现读写饿死的情况,又因为在使用索引的时候用的是行锁,锁的粒度小,竞争相同锁的情况就少,就增加了并发处理,所以并发读写的效率还是很优秀的,问题在于索引查询后的根据主键的二次查找导致效率低;

ps:为什innodb的索引叶子节点存的是主键而不是像mysism一样存数据的物理地址指针吗?如果存的是物理地址指针不就不需要二次查找了吗,这也是我开始的疑惑,根据mysism和innodb数据存储方式的差异去想
所以innodb为了避免二次查找可以使用索引覆盖技术,无法使用索引覆盖的,再延伸一下就是基于索引覆盖实现延迟关联;
不知道什么是索引覆盖的,建议你无论如何都要弄清楚它是怎么回事!

2.explain命令

2.1 id

id有一组数字组成。表示一个查询中各个子查询的执行顺序;

  • id相同执行顺序由上至下。
  • id不同,id值越大优先级越高,越先被执行。
  • id为null时表示一个结果集,不需要使用它查询,常出现在包含union等查询语句中。

2.2 select_type

每个子查询的查询类型,一些常见的查询类型。

  • SIMPLE 不包含任何子查询 或union等查询
  • PRIMARY 包含子查询 外层查询就显示为 PRIMARY
  • SUBQUER Y 在select或 where字句中包含的查询
  • DERIVED from字句中包含的查询
  • UNION 出现在 union后的查询语句中
  • UNION RESULT 从UNION 中获取结果集,例如上文的

2.3 type

访问类型

  • ALL 扫描全表数据
  • index 遍历索引
  • range 索引范围查找
  • ref 使用非唯一索引查找数据
  • eq_ref 在join查询中使用PRIMARY KEY or UNIQUE NOT NULL索引关联。

2.4 possible_keys

可能使用的索引,注意不一定会使用。查询涉及到的字段上若存在索引,则该索引将被
列出来。当该列为 NULL时就要考虑当前的SQL是否需要优化了。

2.5 key

显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL。
查询中若使用了覆盖索引,则该索引仅出现在key列表中

2.6 extra

  1. Using index 使用覆盖索引
  2. Using where 使用了用where子句来过滤结果集
  3. Using filesort 使用文件排序,使用非索引列进行排序时出现,非常消耗性能,尽量优化。
  4. Using temporary 使用了临时表 sql优化的目标可以参考阿里开发手册
    【推荐】SQL性能优化的目标:至少要达到 range 级别,要求是ref级别,如果可以是consts 好。
    说明: 1) consts 单表中 多只有一个匹配行(主键或者唯一索引),在优化阶段即可读取到数据。
    2) ref 指的是使用普通的索引(normal index)。
    3) range 对索引进行范围检索。

3.超大分页怎么处理?

超大的分页一般从两个方向上来解决.
数据库层面,这也是我们主要集中关注的(虽然收效没那么大),类似于select * from table where age

20 limit 1000000,10这种查询其实也是有可以优化的余地的. 这条语句需要load1000000数据然
后基本上全部丢弃,只取10条当然比较慢. 当时我们可以修改为select * from table where id in
(select id from table where age > 20 limit 1000000,10).这样虽然也load了一百万的数据,但是由
于索引覆盖,要查询的所有字段都在索引中,所以速度会很快. 同时如果ID连续的好,我们还可以select

  • from table where id > 1000000 limit 10,效率也是不错的,优化的可能性有许多种, 但是核心思想
    都一样,就是减少load的数据.
    从需求的角度减少这种请求…主要是不做类似的需求(直接跳转到几百万页之后的具体某一页.只允
    许逐页查看或者按照给定的路线走,这样可预测,可缓存)以及防止ID泄漏且连续被人恶意攻击.
    解决超大分页,其实主要是靠缓存,可预测性的提前查到内容,缓存至redis等k-V数据库中,直接返回即可.
    在阿里巴巴《Java开发手册》中,对超大分页的解决办法是类似于上面提到的第一种.
    【推荐】利用延迟关联或者子查询优化超多分页场景。 说明:MySQL并不是跳过offset
    行,而是取offset+N行,然后返回放弃前offset行,返回N行,那当offset特别大的时候,效率就非常的
    低下,要么控制返回的总页数,要么对超过特定阈值的页数进行SQL改写。 正例:先快速定位需要获取
    的id段,然后再关联:
    SELECT a.* FROM 表1 a,(select id from 表1 where 条件 LIMIT 100000,20) b w here
    a.id=b.id

4.慢日志

用于记录执行时间超过某个临界值的SQL日志,用于快速定位慢查询,为我们的优化做参考。

  • 开启慢查询日志
    配置项:slow_query_log 可以使用show variables like ‘slov_query_log’查看是否开启,如果状态值为OFF,可以使用set GLOBAL slow_query_log = on来开启,它会在datadir下产生一个xxx-slow.log的文件。
  • 设置临界时间
    配置项:long_query_time 查看:show VARIABLES like 'long_query_time',单位秒设置:set
    long_query_time=0.5
    实操时应该从长时间设置到短的时间,即将 慢的SQL优化掉
    查看日志,一旦SQL超过了我们设置的临界时间就会被记录到xxx-slow.log中

4.1 优化

是查询
条件没有命中索引?是 load了不需要的数据列?还是数据量太大?
首先分析语句,看看是否load了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。
分析语句的执行计划,然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。

5.具体优化方面

5.1 查询

标签:语句,sql,查询,索引,SQL,优化,id
From: https://www.cnblogs.com/lwx11111/p/18343482

相关文章

  • 003.flask与Mysql的连接以及增删改查
    Flask与Mysql的连接以及在Flask中对数据库进行增删改查python解释器:3.8.3版本flask==2.2.2版本flask_sqlalchemy=3.1.1flask_migrate==4.0.71.创建文件并且配置创建一个大文件在该文件中进行创建static(静态),templates(动态文件),app.py文件将大文件移到vsc......
  • mysql8安装和部署
    mysql8.0详细安装教程参考文章 一、拉取mysql8.0数据库镜像dockerpullmysql:8.0二、创建配置、数据、日志挂载目录mkdir-p/data/mysql/confmkdir-p/data/mysql/datamkdir-p/data/mysql/logs三、新建my.cnf配置文件1、进入配置文件夹cd/data/mysql/conf2......
  • lg省选计划笔记-基础优化技巧1
    基础优化技巧1三分求单峰函数极值点丢弃极值点一定不在的点,注意不能用于非严格单调的函数。由于区间长度可以随便取,可以把分段点取得很近,这个时候就相当于二分斜率前面比0大,极值点处等于0,后面小于001分数规划略。模型特征:答案是比率形式(取对数可以把根式和次方转换为乘......
  • Oracle捕捉SQL语法错误的10035事件
    Oracle数据库中,有的时候新上的程序,会出现与数据库建立了会话,但是传输的SQL是错误的情况,这个时候,我们需要打开oracle10035事件。ALTERSYSTEMSETEVENTS'10035tracenamecontext forever,level1;打开后,在alert文件中,会出现所有解析失败的SQL.解析失败的原因总结......
  • ORA-01555 caused by SQL statement below (SQL ID
    在Oracle数据库种,比较常见的一个错误是ORA-01555。报错如下:我依据这个sql_id去找对应的sql,发现通常是如下类似的sql。即程序的sql中嵌入一个具体的包含日期的条件,这个sql在执行的初期由于数据量较少,大概没有什么问题,但是一年两年数据越来越大,就会出现ORA-01555,即要查找的......
  • MES系统如何精准采集与对接设备数据,全面优化设备管理
    一、MES系统如何采集和对接设备数据MES系统(ManufacturingExecutionSystem,制造执行系统)采集和对接设备数据主要通过以下几种方式实现:手工录入:这是最基础的数据采集方式,通过操作人员在MES系统界面上手动输入数据。适用于数据量较小、实时性要求不高的场景,但存在数据准确......
  • mysql分区自动维护(SpringBoot+MybatisPlus)
    1.环境SpringBoot+MybatisPlus+MySQL2.简介通过定时器@Scheduled每日触发,查询当前库中所有分区表(这里以时间段进行分区)判断剩余分区是否小于自定义预留分区(无自定义预留分区则取默认分区配置),若小于预留分区时,自动创建分区至配置分区数判断已有分区是否大于自定义保留分......
  • springboot多数据源整合及使用(一个oracle,两个mysql)
    在开发工作中,会遇到需要使用多个数据源的情况,比如项目一开始只有oracle,后面需要追加两个mysql数据源使用,这时候就需要配置多数据源了.首先,配置文件的编写:版本如下spring:datasource:db1:driver-class-name:com.mysql.cj.jdbc.Driverurl:......
  • 系统整容纪:用知识来"武装"自己~认识MySQL的锁与事务
    本文通过介绍在实际工作中一次异常排查引发的自我思考与学习,来使得读者受到一定的启发,从而迸发出星星点光,扩展出自己独有的思路,进而在工作中不断的挖掘自我不足之处,同时通过学习与"锻炼"来不断地强大自己。分享工作中的点点滴滴,贯彻千里之行,始于足下,最终以微不足道的量变引起化蝶......
  • 速卖通、美客多自养号经验分享:满足测评条件与Listing优化秘诀
    Listing,即产品在电商平台上的展示页面,是吸引顾客、促进销售的关键窗口。为了在众多竞品中脱颖而出,卖家需精心优化Listing的每一个细节,从类别选择到描述撰写,每一步都至关重要。以下是Listing优化的五大核心策略:1. 类别精准定位分类精准:正确选择产品所属的分类,甚至可考虑添加......