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 Connector/J 8.0.31版本带来了许多改进和修复,包括兼容性提升、性能优化和安全增强。例如,它支持MySQL 8.0的新特性,如JSON字段处理和窗口函数。在JMeter中,只需将这个jar文件放入`lib`目录,JMeter就能...
在本例中,该JAR文件包含了实现JDBC驱动所需的类和资源,使得Java程序能够连接到MySQL数据库,执行SQL查询,操作数据等。 MySQL Connector/J的工作原理: 1. **连接建立**:当Java应用程序需要访问MySQL数据库时,...
本话题将详细讲解如何利用Flink的SQL Server Change Data Capture (CDC) 连接器版本2.3.0,将SQL Server中的数据实时同步到MySQL数据库。 首先,让我们了解什么是CDC。CDC是一种数据库技术,它能够捕获数据库中的...
MySQL Connector/J是MySQL数据库与Java应用程序之间的重要桥梁,它是一个实现了Java Database Connectivity (JDBC) API的驱动程序,使得Java开发者能够方便地在MySQL数据库上执行SQL查询和操作。在这个"mysql-...
而MySQL Connector/J是MySQL官方提供的JDBC驱动,使得Java应用程序能够无缝地连接到MySQL数据库,执行SQL查询,进行数据读写操作。 MySQL Connector/J 8.0.13 是针对MySQL 8.0.x系列的驱动,这意味着它支持MySQL ...
5.1.37版本相较于更早的版本可能包含了一些性能优化、错误修复以及对新MySQL特性的支持。 总之,MySQL Connector/J是Java开发MySQL数据库应用的必备组件,它的存在使得Java程序员可以方便地利用JDBC接口与MySQL...
6. **连接池**:在实际应用中,为了优化性能和资源利用,通常会使用连接池(如C3P0、HikariCP等),这需要在配置连接池时引入`mysql-connector-java-5.1.27.jar`。 7. **版本兼容性**:`5.1.27`版本的驱动适用于...
3. MySQL 5.7.31特性:MySQL 5.7版本引入了许多改进和新功能,包括InnoDB存储引擎的性能优化、JSON数据类型的支持、增强的性能分析工具、更好的备份和恢复选项,以及对SSL连接的强制支持等。 4. 兼容性和版本选择:...
版本8.0.26的更新可能包含了性能优化、新的特性和对MySQL新版本的支持,以及可能的bug修复。通常,升级驱动到最新版本可以确保最佳的兼容性和安全性。 此外,压缩包中还包含了一个名为"mysql-connector-java-8.0.26...
总之,`mysql-connector-java-8.0.20.jar`是Java开发者连接MySQL 8.0数据库的重要工具,它提供了高效、稳定的数据库访问能力,支持最新的MySQL特性和优化,为Java应用程序与MySQL数据库之间的交互奠定了坚实的基础。
1. **MySQL 5.5.28**:这一版本引入了许多性能优化和新特性。例如,InnoDB存储引擎得到显著改进,支持更大的表空间,提高了并发处理能力,并且支持更多的事务隔离级别。此外,它还增强了SQL查询的性能,特别是对于...
MySQL Connector/J是MySQL数据库与Java应用程序之间的重要桥梁,它是一个实现了Java Database Connectivity (JDBC) API的驱动程序,使得Java开发者能够通过编写Java代码来访问和操作MySQL数据库。`mysql-connector-...
例如,可能包括对SQL查询优化器的改进,新的功能添加,以及对旧有bug的修复。然而,具体改动需要查看官方的发行说明来获取详细信息。 MySQL Connector/J遵循JDBC(Java Database Connectivity)规范,它是Java...
这个驱动包允许Java程序通过JDBC(Java Database Connectivity)接口连接到MySQL服务器,执行SQL查询、事务处理等数据库操作。 `mysql-connector-java-5.1.27.jar`是该驱动包的核心文件,包含了所有必要的类和资源...
它允许Java应用程序通过JDBC API与MySQL数据库进行通信,执行SQL查询、事务处理、数据插入、更新和删除等操作。MySQL Connector/J实现了JDBC接口,使得Java开发者可以使用标准的JDBC API来操作MySQL数据库,无需了解...
总之,MySQL Connector/J 8.0.22是Java开发者与MySQL数据库互动的关键组件,它提供了丰富的功能和优化,使得在Java应用程序中使用MySQL变得简单而高效。正确配置和使用这个驱动,可以极大地提升开发效率和应用程序的...
MySQL-server是MySQL的核心服务组件,负责处理来自客户端的请求,执行SQL语句,并管理数据库的存储和事务处理。5.6.29版本引入了InnoDB存储引擎的改进,如更好的行锁定机制,更高效的全文索引,以及对并行复制的支持...
MySQL是世界上最受欢迎的关系型数据库管理系统之一,而`mysql-connector-java`则是MySQL官方提供的Java数据库连接器,用于在Java应用程序中与MySQL服务器进行通信。在这个话题中,我们将深入探讨`mysql-connector-...
MySQL Connector/J 5.0.3版本可能包含了一些特定的改进和修复,比如性能优化、新的功能支持或者对旧版MySQL服务器的兼容性增强。不过,由于具体细节没有给出,我们无法详细阐述这些变更。对于使用这个版本的开发者来...
2. **InnoDB存储引擎优化**:InnoDB是MySQL默认的事务处理引擎,8.3.0版本可能会进一步优化其性能,包括更快的索引构建、更高效的锁机制以及更好的内存管理。 3. **窗口函数**:这是MySQL 8.0引入的新特性,允许在...