`
youyu4
  • 浏览: 441787 次
社区版块
存档分类
最新评论

MySQL-- SQL优化经过

 
阅读更多

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;

 

有索引,速度还算可以



 

 

问题所在

 

  1. 这里用了in,如果in里面的数据比较多,索引就可能会没有(InnoDB几十条数据就会出现),影响执行速度。
  2. 这里条件用了OR,想要改SQL不容易。

 

 

 

修改前的思考,解决方法

 

  1. 用Between代替IN,不过这里是IN里面用了子查询,所以不能用。
  2. 用Exists代替IN,试了下,结果反而没了索引,速度更慢。
  3. 用Union All代替IN或者AND或者OR,这种方法在这里的IN行不通,因为IN里面的ID很多。
  4. 用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条件的数据合并在一起了,而可以思考是否过滤重复。

  • 大小: 16.3 KB
分享到:
评论

相关推荐

    jdbc-mysql-connector-j-8.0.31.jar jdbc-sqljdbc41.jar

    MySQL Connector/J 8.0.31版本带来了许多改进和修复,包括兼容性提升、性能优化和安全增强。例如,它支持MySQL 8.0的新特性,如JSON字段处理和窗口函数。在JMeter中,只需将这个jar文件放入`lib`目录,JMeter就能...

    mysql-connector-java-5.1.40.zip和mysql-connector-java-5.1.10.jar

    在本例中,该JAR文件包含了实现JDBC驱动所需的类和资源,使得Java程序能够连接到MySQL数据库,执行SQL查询,操作数据等。 MySQL Connector/J的工作原理: 1. **连接建立**:当Java应用程序需要访问MySQL数据库时,...

    使用flink-connector-sqlserver-cdc 2.3.0把数据从SQL Server实时同步到MySQL中

    本话题将详细讲解如何利用Flink的SQL Server Change Data Capture (CDC) 连接器版本2.3.0,将SQL Server中的数据实时同步到MySQL数据库。 首先,让我们了解什么是CDC。CDC是一种数据库技术,它能够捕获数据库中的...

    mysql-connector-java-8.0.11

    MySQL Connector/J是MySQL数据库与Java应用程序之间的重要桥梁,它是一个实现了Java Database Connectivity (JDBC) API的驱动程序,使得Java开发者能够方便地在MySQL数据库上执行SQL查询和操作。在这个"mysql-...

    mysql-connector-java-8.0.13.jar

    而MySQL Connector/J是MySQL官方提供的JDBC驱动,使得Java应用程序能够无缝地连接到MySQL数据库,执行SQL查询,进行数据读写操作。 MySQL Connector/J 8.0.13 是针对MySQL 8.0.x系列的驱动,这意味着它支持MySQL ...

    mysql-connector-java-5.1.37.rar

    5.1.37版本相较于更早的版本可能包含了一些性能优化、错误修复以及对新MySQL特性的支持。 总之,MySQL Connector/J是Java开发MySQL数据库应用的必备组件,它的存在使得Java程序员可以方便地利用JDBC接口与MySQL...

    mysql连接包mysql-connector-java-5.1.27.jar

    6. **连接池**:在实际应用中,为了优化性能和资源利用,通常会使用连接池(如C3P0、HikariCP等),这需要在配置连接池时引入`mysql-connector-java-5.1.27.jar`。 7. **版本兼容性**:`5.1.27`版本的驱动适用于...

    mysql-connector-java-5.1.25, mysql 5.7.31亲测有效

    3. MySQL 5.7.31特性:MySQL 5.7版本引入了许多改进和新功能,包括InnoDB存储引擎的性能优化、JSON数据类型的支持、增强的性能分析工具、更好的备份和恢复选项,以及对SSL连接的强制支持等。 4. 兼容性和版本选择:...

    mysql-connector-java-8.0.26.jar

    版本8.0.26的更新可能包含了性能优化、新的特性和对MySQL新版本的支持,以及可能的bug修复。通常,升级驱动到最新版本可以确保最佳的兼容性和安全性。 此外,压缩包中还包含了一个名为"mysql-connector-java-8.0.26...

    mysql-connector-java-8.0.20.jar

    总之,`mysql-connector-java-8.0.20.jar`是Java开发者连接MySQL 8.0数据库的重要工具,它提供了高效、稳定的数据库访问能力,支持最新的MySQL特性和优化,为Java应用程序与MySQL数据库之间的交互奠定了坚实的基础。

    mysql-5.5.28资源文件(mysql-5.5.28-win32.msi)

    1. **MySQL 5.5.28**:这一版本引入了许多性能优化和新特性。例如,InnoDB存储引擎得到显著改进,支持更大的表空间,提高了并发处理能力,并且支持更多的事务隔离级别。此外,它还增强了SQL查询的性能,特别是对于...

    mysql-connector-java-5.1.47 jar包

    MySQL Connector/J是MySQL数据库与Java应用程序之间的重要桥梁,它是一个实现了Java Database Connectivity (JDBC) API的驱动程序,使得Java开发者能够通过编写Java代码来访问和操作MySQL数据库。`mysql-connector-...

    mysql-connector-java-8.0.23.zip

    例如,可能包括对SQL查询优化器的改进,新的功能添加,以及对旧有bug的修复。然而,具体改动需要查看官方的发行说明来获取详细信息。 MySQL Connector/J遵循JDBC(Java Database Connectivity)规范,它是Java...

    mysql-connector-java-5.1.27

    这个驱动包允许Java程序通过JDBC(Java Database Connectivity)接口连接到MySQL服务器,执行SQL查询、事务处理等数据库操作。 `mysql-connector-java-5.1.27.jar`是该驱动包的核心文件,包含了所有必要的类和资源...

    mysql-connector-java-8.0.17.jar.zip

    它允许Java应用程序通过JDBC API与MySQL数据库进行通信,执行SQL查询、事务处理、数据插入、更新和删除等操作。MySQL Connector/J实现了JDBC接口,使得Java开发者可以使用标准的JDBC API来操作MySQL数据库,无需了解...

    mysql-connector-java-8.0.22.jar

    总之,MySQL Connector/J 8.0.22是Java开发者与MySQL数据库互动的关键组件,它提供了丰富的功能和优化,使得在Java应用程序中使用MySQL变得简单而高效。正确配置和使用这个驱动,可以极大地提升开发效率和应用程序的...

    MySQL-client-5.6.29-1.linux_glibc2.5.x86_64,MySQL-server-5.6.29-1.linux_glibc

    MySQL-server是MySQL的核心服务组件,负责处理来自客户端的请求,执行SQL语句,并管理数据库的存储和事务处理。5.6.29版本引入了InnoDB存储引擎的改进,如更好的行锁定机制,更高效的全文索引,以及对并行复制的支持...

    mysql-connector-java-5.1.47.jar

    MySQL是世界上最受欢迎的关系型数据库管理系统之一,而`mysql-connector-java`则是MySQL官方提供的Java数据库连接器,用于在Java应用程序中与MySQL服务器进行通信。在这个话题中,我们将深入探讨`mysql-connector-...

    mysql-connector-java-5.0.3.zip

    MySQL Connector/J 5.0.3版本可能包含了一些特定的改进和修复,比如性能优化、新的功能支持或者对旧版MySQL服务器的兼容性增强。不过,由于具体细节没有给出,我们无法详细阐述这些变更。对于使用这个版本的开发者来...

    mysql-server-mysql-8.3.0.tar.gz

    2. **InnoDB存储引擎优化**:InnoDB是MySQL默认的事务处理引擎,8.3.0版本可能会进一步优化其性能,包括更快的索引构建、更高效的锁机制以及更好的内存管理。 3. **窗口函数**:这是MySQL 8.0引入的新特性,允许在...

Global site tag (gtag.js) - Google Analytics