首页 > 数据库 >【知识点】常见的SQL优化手段

【知识点】常见的SQL优化手段

时间:2024-04-15 17:48:04浏览次数:25  
标签:知识点 使用 查询 索引 SQL 优化 select

问:有哪些常见的SQL优化手段?

这也是个高频面试题,并且并非面试造火箭的那种问题,实际项目中也会有非常多的地方需要进行SQL优化

避免使用 Select *

  • select *中,无用字段会增加网络带宽消耗,特别是varcharblobtext等大字段
  • select *无法使用Mysql优化器覆盖索引的优化。

  • 覆盖索引:即一个查询可以完全通过索引来满足,不需要回表
  • 回表:根据非聚集索引查询到主键,然后根据主键查询其他数据。

分页优化

Mysql分页时,并不是跳过 offset,而是取 offset + N 行,然后丢弃 offset行,只返回N行。

并且,offset 越大、N 越大、select出的字段越多,耗时就越久。

数据量少时,分页耗时还是比较少的。

但是上数据量上百万甚至千万的时候,直接limit 1000000, 20是非常慢的。

优化方案:先根据排序规则及limit条件查询出主键,然后根据主键关联到表本身。

即把

select t.* form the_table where 条件 limit 1000000, 20 

修改为:

select t1.* from the_table t1,
(select id from the_table where 条件 limit 1000000, 20) as t2 
where t1.id = t2.id

并且条件种的字段尽量创建了索引。

尽量避免多表Join

join 关联的效率不算很高,多个表关联时会使用嵌套循环,如果关联字段没有索引,会直接使用笛卡尔积实现 join,导致全表扫描,效率很低。

两种解决方式:

  1. 单表查询,根据查询结果进行二次查询,最后在 Service 层进行关联。
  2. 数据冗余:把重要字段冗余在表中,尽可能避免关联查询。

推荐使用第一种方式,因为数据库的计算资源更加宝贵,Service层可以很方便的水平扩展。并且如果数据量非常大的时候也会进行分库分表,这也会限制join。

建议不要使用外键与级联

外键概念应该在应用层解决。

选择合适的字段类型

存储字节越小,占用空间就越小,性能也就越好。

尽量使用 union all 代替 union

union会把结果集进行去重操作,更耗时。

批量操作

操作数据时,能批量操作尽量批量处理,减少请求数据库的次数。

使用Explain分析SQL

正确使用索引

适合作为索引的字段

  • 不为null的字段:索引字段应尽量不为null,对于数据为null的字段,数据库比较难优化。如果字段频繁被查询,又无法避免为null,可以使用-1、0、true、false等语义清晰地短字符作为代替。
  • 被频繁查询的字段
  • 被作为条件查询的字段
  • 频繁需要排序的字段
  • 频繁用于外连接的字段

被频繁更新的字段应慎重建立索引

虽然索引能带来查询上的效率,但是维护索引的成本也不小。
如果字段不经常被查询,反而经常被修改,那不应该在这种字段上创建索引。

尽可能创建联合索引,而不是单列索引

索引需要占用空间,如果是联合索引,多个字段在一个索引上,可以节省空间,并且修改数据时效率也会提升。

避免冗余索引

考虑在字符串类型上使用前缀索引代替普通索引

前缀索引只适用于字符串类型,比普通索引占用更少的空间

避免索引失效

  • 使用 select *查询
  • 创建了联合索引,但是没有遵循最左匹配原则
  • 在索引列上进行计算、函数、类型转换等操作
  • %开头的like查询,比如like '%abc'
  • 发生隐式转换
  • 查询时使用条件1 or 条件2,如果条件1或者条件2中存在未创建索引的字段,就不会使用索引

标签:知识点,使用,查询,索引,SQL,优化,select
From: https://www.cnblogs.com/code-blog/p/18136583

相关文章

  • Winodows安装Mysql 8.0.36 简单教程
    下载https://dev.mysql.com/downloads/mysql/选择下载简单版本即可安装1.解压将下载下来的安装包进行解压2.mysql初始化用cmd进入的mysql的解压包的bin目录里,执行初始化命令mysqld--initialize--console记录一下mysql初始化密码,备用。3.启动mysqlnetstartmy......
  • MySQL锁、事务和索引
    并发事务的控制方式是MVCC和行锁按范围分:表级锁、页锁、行级锁(锁一行或者多行)(记录索、间隙锁、临键锁(可重复读默认用这个做行锁,除非是主键和唯一索引会使用记录索))按功能分:读锁(S)、写锁(X)意向锁是表级锁,分为意向共享锁、意向排他锁,用于协调表锁和行锁的关系,事务想要在某些行上加共......
  • 一些有意思的sql
    createtemporarytabletmp_tableselect*,ROW_NUMBER()over(orderbydiff)asrank_numfrom(SELECT*,sum(num)over(orderbyoverdateROWSBETWEENUNBOUNDEDPRECEDINGANDCURRENTROW)-18ASdiffFROMmedical_goodsWHEREitem_id=7AN......
  • MySQL优化:索引
    1、谈一下你对于mysql索引的理解?(为什么mysql要选择B+树来存储索引)​ mysql的索引选择B+树作为数据结构来进行存储,使用B+树的本质原因在于可以减少IO次数,提高查询的效率,简单点来说就是可以保证在树的高度不变的情况下可以存储更多的数据:​ 1、在MYSQL的数据库中,表的真实数据和......
  • JVM性能优化 —— 类加载器,手动实现类的热加载
    一、类加载的机制的层次结构每个编写的”.java”拓展名类文件都存储着需要执行的程序逻辑,这些”.java”文件经过Java编译器编译成拓展名为”.class”的文件,”.class”文件中保存着Java代码经转换后的虚拟机指令,当需要使用某个类时,虚拟机将会加载它的”.class”文件,并创建对应的cl......
  • Mysql安装和远程登录--Centos7
    在Centos7中使用的包管理工具是yum,当然使用包管理工具安装也是最方便的。本文操作内容需要在root用户下,否则有些步骤无法成功执行。系统环境信息展示安装MySQL提供的RPMwgethttps://dev.mysql.com/get/mysql80-community-release-el7-11.noarch.rpm检查是否下载成功......
  • 析构函数与 -O2 优化的一个问题
    在赋值时,我们需要先对原有对象调用析构函数。我的析构函数实现如下:~vector() { for(ptr*itr=begin_p;itr!=finish_p;itr++) { delete*itr; } delete[]begin_p; begin_p=nullptr;finish_p=nullptr;end_p=nullptr; }不使用-O2优化,程序运行正常,调用完析构函......
  • 数据库SQL注入攻击以及解决方案
    数据库SQL注入攻击以及解决方案--数据库SQL注入攻击selectcount(*)from表whereLoginID='lqwvje'andpwd='123'--拿上面的一个经常用的用户登入实例正常情况下是没有问题count>0即可以登入成功--用户名一但输入了数据库特殊字符如一下一段代码那就可以正常登入......
  • PGSQL 单sql多insert例子
    --INITdatabaseCREATETABLEmsg(msgIdchar(32)PRIMARYKEYcomment'ulid',uidbigintnotnull,contextnotnull);createtableseum(clientIdint,uidbigintnotnull,msgIdchar(32)notnull,cointnotnulldefault0,p......
  • Sql Server数据库 读写分离之发布与订阅
    SqlServer数据库读写分离之发布与订阅1、配置分发2、发布3、订阅订阅我在虚拟机上,注意配置分发,发布,订阅我在这里,三个是同一内网,内网一定要联通,服务器的端口也要打开,不然没发访问......