MySQL-- SQL优化经过
背景:有一个SQL如下
SELECT ut.* FROM user_transaction ut WHERE tx_type IN (1, 4, 8) AND tx_status = 1 AND share_public = 1 AND user_id != 103 AND (peer_user_id IS NULL OR peer_user_id != 103) AND ( user_id IN (SELECT DISTINCT friend_user_id from user_friend uf WHERE uf.user_id = 103 AND uf.status = 1) AND peer_user_id IN (SELECT DISTINCT friend_user_id from user_friend uf WHERE uf.user_id = 103 AND uf.status = 1) ) ORDER BY tx_date DESC LIMIT 1, 10; --也有下面OR的情况,业务需要 SELECT ut.* FROM user_transaction ut WHERE tx_type IN (1, 4, 8) AND tx_status = 1 AND share_public = 1 AND user_id != 103 AND (peer_user_id IS NULL OR peer_user_id != 103) AND ( user_id IN (SELECT DISTINCT friend_user_id from user_friend uf WHERE uf.user_id = 103 AND uf.status = 1) OR peer_user_id IN (SELECT DISTINCT friend_user_id from user_friend uf WHERE uf.user_id = 103 AND uf.status = 1) ) ORDER BY tx_date DESC LIMIT 1, 10;
有索引,速度还算可以
问题所在
- 这里用了in,如果in里面的数据比较多,索引就可能会没有(InnoDB几十条数据就会出现),影响执行速度。
- 这里条件用了OR,想要改SQL不容易。
修改前的思考,解决方法
- 用Between代替IN,不过这里是IN里面用了子查询,所以不能用。
- 用Exists代替IN,试了下,结果反而没了索引,速度更慢。
- 用Union All代替IN或者AND或者OR,这种方法在这里的IN行不通,因为IN里面的ID很多。
- 用Inner join代替IN,这是网上的方法
实际修改
用Between代替IN
这个方法直接就没有试,因为不合适。
用Exists代替IN
修改如下:
SELECT distinct pub_name FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE type = 'business') SELECT DISTINCT pub_name FROM publishers WHERE EXISTS (SELECT * FROM titles WHERE pub_id = publishers.pub_id AND type = 'business')
但是实际情况反而索引没有了,执行速度更慢。
用Inner join代替IN
写法如下:
SELECT ut.* FROM user_transaction ut INNER JOIN user_friend uf ON uf.friend_user_id = ut.user_id AND uf.user_id = 103 AND uf.status = 1 INNER JOIN user_friend uf2 ON uf2.friend_user_id = ut.peer_user_id AND uf2.user_id = 103 AND uf2.status = 1 WHERE tx_type IN (1, 4, 8) AND tx_status = 1 AND share_public = 1 AND ut.user_id != 103 AND (peer_user_id IS NULL OR peer_user_id != 103) ORDER BY tx_date DESC LIMIT 1, 10;
这样写,既保证了索引,对SQL的影响也不大,但是还剩最后一个问题,就是怎么将OR的数据合在一起。
使用Union All 或Union
写法如下:
( SELECT ut.* FROM user_transaction ut INNER JOIN user_friend uf ON uf.friend_user_id = ut.user_id AND uf.user_id = 103 AND uf.status = 1 WHERE tx_type IN (1, 4, 8) AND tx_status = 1 AND share_public = 1 AND ut.user_id != 103 AND (peer_user_id IS NULL OR peer_user_id != 103) ) UNION ( SELECT ut.* FROM user_transaction ut INNER JOIN user_friend uf ON uf.friend_user_id = ut.peer_user_id AND uf.user_id = 103 AND uf.status = 1 WHERE tx_type IN (1, 4, 8) AND tx_status = 1 AND share_public = 1 AND ut.user_id != 103 AND (peer_user_id IS NULL OR peer_user_id != 103) ) ORDER BY tx_date DESC LIMIT 0, 10;
这样就将OR条件的数据合并在一起了,而可以思考是否过滤重复。
相关推荐
mysql-sql优化-小米开源-soar 。。。。。
计算机-mysql-基于SQL Server的数据仓库性能优化方法研究与应用.pdf
从Oracle的SQL优化到MySQL的SQL优化
1. SQL优化 1 1.1. 优化实战 1 1.1.1. 策略1.尽量全值匹配 1 1.1.2. 策略2.最佳左前缀法则 2 1.1.3. 策略3.不在索引列上做任何操作 2 1.1.4. 策略4.范围条件放最后 3 1.1.5. 策略5.覆盖索引尽量用 3 1.1.6. 策略6.不...
mysql优化从以下几个方面介绍 mysql的架构 索引优化分析 查询截取分析 mysql锁机制 主从复制
05-VIP-Mysql索引优化实战二.pdf
MySQL性能优化 SQL优化方法技巧
MySQL进阶-SQL优化(插入和主键优化)
2023最新mysql的sql语句优化方法技巧面试题总结.docx2023最新mysql的sql语句优化方法技巧面试题总结.docx2023最新mysql的sql语句优化方法技巧面试题总结.docx2023最新mysql的sql语句优化方法技巧面试题总结.docx2023...
本书希望能够通过一步步详细介绍SQL优化的方法,帮助读者分 析和调优有问题的SQL语句。 主要内容 ● 找出收集和诊断问题必备的分析命令 ● 创建MySQL索引来改进查询性能 ● 掌握MySQL的查询执行计划 ● 找...
30道经典mysql面试题 当面试MySQL数据库开发职位时,以下是一些经典的MySQL面试题供参考: 什么是数据库?什么是关系数据库管理系统(RDBMS)? 什么是SQL?列举一些常见的SQL命令。 什么是索引?为什么使用...
MySQL SQL优化的小册子。 对优化这块重点阐述了相关原理与技术手段。
2. SQL优化 2.1优化SQL的一般步骤 2.2 索引问题. 2.3两个常用的优化技巧 2.4常用SQL优化 2.5常用SQL技巧 3.优化数据库对象 3.1优化表的数据类型逆规范化 3.2提高查询速度 4.锁问题 4.1MyISQM表锁 4.2...
基于Mysql数据库的SQL优化 亲测
MySQL Workbench 提供了一些可视化工具来创建、执行和优化 SQL 查询。SQL Editor 具有语法高亮显示、自动填充、SQL 代码段重用和 SQL 执行历史记录等功能。开发人员可以通过 Database Connections Panel 轻松管理...
go-mysql-server是一个SQL引擎,能解析标准SQL(基于MySQL语法)并优化查询。 它提供了简单的接口,允许自定义表格数据源实现。提供与MySQL协议兼容的服务器实现。 这意味着它与MySQL ODBC,JDBC或默认的MySQL客户端...
MySQL架构执行与SQL性能优化-MySQL高并发详解课程,课程的目标简单明确,核心就是MySQL的性能优化与高并发。课程内容进行了精华的浓缩,有四大内容主旨,MySQL架构与执行流程,MySQL索引原理详解,MySQL事务原理与...
MySQL数据库优化SQL篇.ppt,适用于企业级项目开发
MySQL数据库-事务、锁及SQL优化