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

SQL 优化笔记:提高查询速度

SQL 优化笔记:提高查询速度

SQL 优化是提升数据库性能的关键环节。以下是一些常见的 SQL 优化策略,包含每种方法的原因和建议,可以帮助提高查询速度和整体性能。

1. 使用索引

1.1 创建索引

原因:索引可以大大加快数据检索速度,通过创建索引,数据库可以更快地定位到所需数据,而无需扫描整个表。 建议:为查询中经常作为WHERE条件、JOIN条件或ORDER BY的列创建索引。

  • 单列索引:适用于经常作为查询条件的单列。

    sqlCopy CodeCREATE INDEX idx_column_name ON table_name(column_name);
    
  • 联合索引:适用于多个列一起作为查询条件的情况。

    sqlCopy CodeCREATE INDEX idx_column1_column2 ON table_name(column1, column2);
    
  • 注意:索引会增加写入操作的开销,避免为每个查询创建过多索引。

1.2 索引选择

原因:选择性高的列(即唯一值多)能有效提高索引效率。 建议

  • 优先索引选择性高的列,如主键或唯一约束列。
  • 避免过多索引:每增加一个索引都会带来额外的维护开销,特别是对于写操作(插入、更新、删除)。

2. 优化查询语句

2.1 使用合适的查询条件

原因:不必要的 SELECT * 或函数在 WHERE 子句中会导致全表扫描或失去索引效率。 建议

  • 选择需要的列:只查询实际需要的字段。

    sqlCopy CodeSELECT column1, column2 FROM table_name WHERE condition;
    
  • 避免在 WHERE 子句中使用不必要的函数:函数调用可能会导致索引失效。

    sqlCopy Code-- 不推荐
    SELECT * FROM table_name WHERE YEAR(date_column) = 2023;-- 推荐
    SELECT * FROM table_name WHERE date_column BETWEEN '2023-01-01' AND '2023-12-31';
    

2.2 使用 JOIN 而非子查询

原因JOIN 通常比子查询性能更优,尤其是在处理大数据集时。 建议

  • 使用 JOIN 替代子查询:在可能的情况下,尽量使用连接查询而非嵌套查询。

    sqlCopy Code-- 子查询
    SELECT * FROM orders WHERE customer_id IN (SELECT customer_id FROM customers WHERE status = 'active');-- JOIN 查询
    SELECT orders.* FROM orders JOIN customers ON orders.customer_id = customers.customer_id WHERE customers.status = 'active';
    

2.3 小表驱动大表

原因:小表驱动大表,也就是说用小表的数据集驱动大表的数据集。
假如有order和user两张表,其中order表有10000条数据,而user表有100条数据。
这时如果想查一下,所有有效的用户下过的订单列表。
可以使用in关键字实现:

select * from order
where user_id in (select id from user where status=1)

也可以使用exists关键字实现:

select * from order
where exists (select 1 from user where order.user_id = user.id and status=1)

前面提到的这种业务场景,使用in关键字去实现业务需求,更加合适。
为什么呢?
因为如果sql语句中包含了in关键字,则它会优先执行in里面的子查询语句,然后再执行in外面的语句。如果in里面的数据量很少,作为条件查询速度更快。
而如果sql语句中包含了exists关键字,它优先执行exists左边的语句(即主查询语句)。然后把它作为条件,去跟右边的语句匹配。如果匹配上,则可以查询出数据。如果匹配不上,数据就被过滤掉了。
这个需求中,order表有10000条数据,而user表有100条数据。order表是大表,user表是小表。如果order表在左边,则用in关键字性能更好。
总结一下:
in 适用于左边大表,右边小表。
exists 适用于左边小表,右边大表。
不管是用in,还是exists关键字,其核心思想都是用小表驱动大表。

2.4 优化分页查询

**原因:**当使用LIMIT和OFFSET进行分页时,随着页码的增加,查询性能会逐渐下降,因为数据库需要扫描越来越多的行来找到所需的起始点。
**建议:**使用基于索引的查询来优化分页,特别是当表很大时。例如,可以记录上一页最后一条记录的某个唯一标识符(如ID),并使用它作为下一页查询的起点。
例子:
优化前(随着页码增加性能下降)

SELECT * FROM user LIMIT 10 OFFSET 100;

优化后(使用上一页的最后一条记录的ID)

SELECT * FROM user WHERE id > LAST_SEEN_ID ORDER BY id LIMIT 10

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Fiddle抓手机app的包
  • 从力扣中等+困难题+表白HTML测试 -- 文心快码(Baidu Comate)
  • 【Orange Pi 5嵌入式C语言编程】-智能指针简单实现
  • 奇门WMS-A和金蝶云星空单据接口对接
  • linux(debian)迁移home到其他物理盘并扩容——————附带详细步骤
  • 基于hadoop的网络流量分析系统的研究与应用
  • 杂谈c语言——5.类型提升
  • 富格林:揭开黑幕面纱实现安全
  • Spark-环境启动
  • Oracle+ASM+High冗余详解及空间计算
  • Ubuntu24.04使用SRS 搭建 RTMP流媒体服务器
  • `kill -9` 和 `pkill`
  • 31集-33集【求助】AIGC返回的对话内容文字转语音失败-《MCU嵌入式AI开发笔记》
  • 驾驭时间之舟:SQL中时序数据处理的深度探索
  • ActiveMQ、RabbitMQ、Kafka、RocketMQ在事务性消息、性能、高可用和容错、定时消息、负载均衡、刷盘策略的区别
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • canvas 绘制双线技巧
  • CentOS7 安装JDK
  • codis proxy处理流程
  • go append函数以及写入
  • golang中接口赋值与方法集
  • JavaScript标准库系列——Math对象和Date对象(二)
  • js数组之filter
  • opencv python Meanshift 和 Camshift
  • Python连接Oracle
  • React Native移动开发实战-3-实现页面间的数据传递
  • React组件设计模式(一)
  • Redis 懒删除(lazy free)简史
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • webgl (原生)基础入门指南【一】
  • 包装类对象
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 实习面试笔记
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 用jquery写贪吃蛇
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • $().each和$.each的区别
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (二)JAVA使用POI操作excel
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (四十一)大数据实战——spark的yarn模式生产环境部署
  • (算法)N皇后问题
  • (五)c52学习之旅-静态数码管
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .mysql secret在哪_MySQL如何使用索引
  • @RequestMapping 和 @GetMapping等子注解的区别及其用法