当前使用版本 3.5.3.1
当前环境信息 Java11 + Mysql8 + postgreSQL
描述bug现象 在PG数据库下,做多表联表查询时,主表中数据量比较大(3w+),会超时
提供问题复现步骤
超时查询语句如下: select * from A left join B on A.b_id = B.id AND B.tenant_id = -1 left join C on A.c_id = C.id AND C.tenant_id = -1 where 1=1 AND A.tenant_id = -1
经验证,若语句如下,则不会超时 select * from A left join B on A.b_id = B.id left join C on A.c_id = C.id where 1=1 AND A.tenant_id = -1 AND B.tenant_id = -1 AND C.tenant_id = -1
期望可以对此进行一定的修改
提供完整堆栈日志(可选)
提供问题复现工程(可选) 请尽量提供复现工程,减少大家排错的时间.
Comment From: huayanYu
在A表数据量巨大的情况下,两个SQL语句的执行速度可能会受到不同因素的影响。为了确定哪种SQL可能执行得更快,我们需要考虑以下几个关键点:
查询条件的位置:
SQL1在JOIN操作中就对B和C表的tenant_id进行了过滤,这可能会减少需要JOIN的数据量,从而减少了最终需要处理的数据量。 SQL2将所有的过滤条件都放在了WHERE子句中,这意味着在执行JOIN操作之前,不会对B和C表的数据进行过滤。 索引的使用:
如果tenant_id字段在B和C表上有索引,SQL1可能会利用这个索引来快速过滤出tenant_id = -1的行,这可能加快了JOIN操作的速度。 SQL2可能会在完成JOIN操作后,再应用WHERE子句中的过滤条件,这可能意味着需要处理更多的数据。 数据库优化器:
不同的数据库优化器可能会采用不同的策略来执行查询。有些优化器可能会识别出在JOIN条件中过滤tenant_id可以减少数据量,而有些优化器可能会等到所有JOIN操作完成后再应用过滤条件。 数据的分布:
如果tenant_id = -1的记录在B和C表中非常少,那么SQL1可能会更快,因为它可以提前过滤掉不符合条件的记录。 如果tenant_id = -1的记录在B和C表中占大多数,那么SQL2可能不会比SQL1慢太多,因为最终需要处理的数据量相似。 查询计划:
执行前,数据库优化器会为每个查询生成一个查询计划。查询计划会展示优化器将如何执行查询,包括是否使用索引、JOIN的顺序等。查看查询计划可以帮助我们理解为什么一个查询比另一个查询更快。 其他因素:
服务器的硬件性能、数据库的配置、并发查询的数量等也会影响查询的执行速度。 基于上述因素,理论上,如果B和C表中的tenant_id = -1的记录相对较少,并且数据库优化器能够识别并利用这一点,SQL1可能会更快,因为它可以在JOIN操作中提前过滤掉不符合条件的记录。然而,这只是一种可能的情况,实际的执行速度还需要依赖于具体的数据库优化器和数据的实际情况。
为了得到准确的答案,最好的方法是在目标数据库上对这两个查询进行实际的性能测试。这可以通过执行EXPLAIN命令(或等效的命令,取决于你使用的数据库系统)来查看查询计划,或者直接通过SELECT语句运行查询并测量执行时间来完成。
Comment From: miemieYaho
你要的sql不合理