首页 > 数据库 >SQL优化

SQL优化

时间:2024-01-20 12:12:28浏览次数:28  
标签:count 索引 innoDB SQL 排序 优化 主键

1、Insert优化

批量插入(一次也不宜太多,500~1000,根据业务情况决定),避免频繁开启、关闭事务

  • 手动提交事务
  • 主键顺序插入(性能高于乱序插入)
  • 大批量的数据插入

如果一次性需要插入大批量数据,使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入

 

 

2、主键优化

在innoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(index organized table IOT)。

  • 页分裂:

页可以为空,页可以填充一半,也可以填充100%。每个页包含了2-N行数据(如果一行数据较大,会行溢出),根据主键排列。

  • 页合并:

当删除一行记录时,实际上记录并没有被物理删除,之上记录被标记(flaged)为删除并且它的空间变得允许被其他记录声明使用。当页中删除的记录达到MERGE_THRESHOLD(合并页的阈值,默认为页的50%,可以自己设置,在创建表或者创建索引时指定),innoDB会开始寻找最靠近的页(前或后)看看是否将两个页合并以优化空间使用。

  • 主键设计原则
  1. 满足业务需求的情况下,尽量降低主键的长度。
  2. 插入数据时,尽量选择顺序插入,选择使用AUTO_INCREMENT自增主键。
  3. 尽量不要使用UUID做主键或者其他自然主键,如身份证号。(UUID无序,长度较长)
  4. 业务操作时,避免对主键的修改。

3、Order by优化:

Explain 查询执行计划信息后,在extra信息中可以看是哪种类型的排序。

  • Using filesort:通过表的索引或全表扫描,读取满足条件的数据行,然后在排序缓冲区sort buffer中完成排序操作,所有不是通过索引直接返回排序结果的排序都叫filesort排序。
  • Using index:通过有序索引顺序扫描直接返回有序数据,这种情况即为using index,不需要额外排序,操作效率高。
  • 创建索引时,可以指定索引的排序规则。

Create index xxx on table(xxx desc, xxx asc)

  • 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则。
  • 尽量使用覆盖索引。
  • 多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC\DESC)。
  • 如果不可避免的出现filesort,大数据量排序时,可以适当增加排序缓冲区大小sort_buffer_size(默认256K)。通过语句show variables like ‘sort_buffer_size’ 可以查看排序缓存区的大小,如果数据超过排序缓冲区大小,那么会在磁盘文件中进行排序,性能低。

4、Group by优化

在分组操作时,可以通过索引来提高效率

分组操作时,索引的使用也是满足最左前缀法则的

5、Limit优化

一个常见又非常头疼的问题就是limit 2000000,10,此时需要MySQL排序前2000010记录,仅仅返回2000000-2000010的记录,其他记录丢弃,查询排序的代价非常大。

优化思路:一般分页查询时,通过创建覆盖索引就够比较好的提高性能,可以通过覆盖索引加子查询形式进行优化。

6、Count优化:

MyISAM引擎把一个表的总行数存在了磁盘上,因此执行count(*)的时候会直接返回这个数,效率很高;

innoDB引擎就麻烦了,它执行count(*)的时候,需要把数据一行一行地从引擎里面读出来,然后累积计数。

  • l Count的几种用法:

Count()是一个聚合函数,对于返回的结果集,一行行地判断,如果count函数的参数 不是NULL,累积值就加1,否则不加,最后返回累计值。

  • l 用法:
    1. count(*):innoDB引擎并不会把全部字段取出来,而是专门做了优化,不取值,服务器直接按行进行累加;
    2. count(主键):innoDB引擎会遍历整张表,把每一行的主键id值都取出来,返回给服务层。服务层拿到主键后,直接按行进行累加(主键不可能为null)。
    3. count(字段):

没有not null约束:innoDB引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,服务层判断是否为null,不为null,基数累加;

有not null约束:innoDB引擎会遍历整张表把每一行的字段值都取出来,返回给服务层,直接按行进行累加。

4. count(1)

InnoDB引擎遍历整张表,但不取值。服务层对于返回的每一行,放一个数字“1”进去,直接进行累加。 

取总记录数的情况下,按照效率排序,count(字段)<count(主键id)<count(1)、count(*),所以尽量使用count(*)。

7、Update优化:

innoDB的行锁是针对索引加的锁,不是针对记录加的锁,更新条件要走索引,并且该索引不能失效,否则会从行锁升级为表锁。

 

标签:count,索引,innoDB,SQL,排序,优化,主键
From: https://www.cnblogs.com/roujingchuxia/p/17976288

相关文章

  • Hive SQL底层执行过程详细剖析
     本文结构采用宏观着眼,微观入手,从整体到细节的方式剖析HiveSQL底层原理。第一节先介绍Hive底层的整体执行流程,然后第二节介绍执行流程中的SQL编译成MapReduce的过程,第三节剖析SQL编译成MapReduce的具体实现原理。HiveHive是什么?Hive是数据仓库工具,再具体点就......
  • MySQL中的加密函数
    本文简单介绍MySQL中的加密函数。MySQL提供了多种加密函数,以下是一些常用的:PASSWORD(str):用于密码加密,通常用于创建用户时对密码进行加密。MD5(str):生成一个128位的加密串,返回一个32位的16进制数。SHA1(str):生成一个160位的加密串,返回一个40位的16进制数。ENCODE(str......
  • SQLServer 分页查询
    SQLServer分页查询方式TOP子句--每页20条记录,第1页selecttop20*fromtceshiorderbyID--第2页(返回ID不是前20条记录)selecttop20*fromtceshiwhereIDnotin(selecttop20IDfromtceshiorderbyID)orderbyIDROW_NUMBER语法[ROW_NUMBER()O......
  • SQL常见面试题(测试工程师)
    用一条 SQL 语句 查询出每门课都大于 60 分的学生姓名。表 scores 如下SELECTname,MIN(score)ashigtfromstudent_scoressgroupbynameHAVINGhigt>60用一条 SQL 语句 查询两门以上不及格课程的同学的学号姓名以及其平均成绩, 并按成绩排序SELECT......
  • MySQL连接池最大连接数设置
    默认连接数的选择应该基于你的应用程序的需求以及数据库服务器的性能和配置。 对于大多数小型和中型应用程序来说,10个连接可能是一个合理的起点。然而,如果你的应用程序具有较高的并发性或处理大量数据库操作,你可能需要增加连接数。否则,在高负载时,连接池中的连接可能会快速耗尽......
  • k8s之构建Mysql和Wordpress集群
    一、实验目的基于Kubernetes集群实现多负载的WordPress应用。将WordPress数据存储在后端Mysql,Mysql实现主从复制读写分离功能。1、准备Kubernetes集群环境root@k8s-master01:~#kubectlgetnodesNAMESTATUSROLESAGEVERSIONk8s-master01Re......
  • Linux离线安装MySQL
    在Linux上离线安装MySQL,可以按照以下步骤进行操作:下载MySQL安装包:去MySQL官网下载适合Linux系统的MySQL安装包,选择一个合适的版本和文件格式进行下载。根据gclib安装对应的版本和架构进行选择。将安装包复制到Linux系统中:将下载的MySQL安装包复制到Linux系统中的一个合适的目录,例......
  • pymysql模块
    支持python代码操作数据库MySQL#安装,不用考虑版本pip3installpymysql1 链接、执行sql、关闭(游标) importpymysqluser=input('用户名:').strip()pwd=input('密码:').strip()#链接conn=pymysql.connect(host='localhost',port=3306,user='ro......
  • 1.19 _fetchSql() 和 getLastSql() 的用法
    1fetchSql()的用法重要点:语法2getLastSql()的用法删除不掉的原因具有外键的那张表叫:主表,也就是details是主表,internet_bar这个是从表当使用:DELETEFROMbusiness_internet_barwhereid=34;删除表中的数据的时候,会发生下面的错误DELETEFROM`business_in......
  • Mysql Row size too large (> 8126)
    问题描述:Rowsizetoolarge(>8126).ChangingsomecolumnstoTEXTorBLOBorusingROW_FORMAT=DYNAMICorROW_FORMAT=COMPRESSEDmayhelp.Incurrentrowformat,BLOBprefixof768bytesisstoredinline.解决问题有几种潜在的解决方案可以解决这个问题。将表转......