OR导致笛卡尔积

近期监控数据库,发现以下语句跑得很慢,原来运行计划走了导致笛卡尔积,来看以下语句:

SQL> explain plan for
  2  SELECT COUNT(*)
  3    FROM "GD_FS"."TZZ_SJ_DEV_DISC_79073" "A2",
  4         "GD_FS"."TZZ_SJ_DEVELOP_MONTH"  "A1"
  5   WHERE "A1"."SERV_ID" = "A2"."SERV_ID"
  6     AND "A1"."STAT_DATE" = "A2"."STAT_DATE"
  7     AND "A2"."ALLO_DISC_TYPE_3" LIKE '%租机%'
  8      OR "A2"."ALLO_DISC_TYPE_3" LIKE '%零预存%';

Explained.

SQL> @getplan
'general,outline,starts'

Enter value for plan type:

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------------------------------------

Plan hash value: 1410945947

------------------------------------------------------------------------------------------------
| Id  | Operation              | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |                       |     1 |    42 |   271M  (2)|999:59:59 |
|   1 |  SORT AGGREGATE        |                       |     1 |    42 |            |          |
|   2 |   CONCATENATION        |                       |       |       |            |          |
|   3 |    MERGE JOIN CARTESIAN|                       |    82G|  3239G|   271M  (2)|999:59:59 |
|*  4 |     TABLE ACCESS FULL  | TZZ_SJ_DEV_DISC_79073 | 22606 |   640K|   743   (2)| 00:00:11 |
|   5 |     BUFFER SORT        |                       |  3663K|    45M|   271M  (2)|999:59:59 |
|   6 |      TABLE ACCESS FULL | TZZ_SJ_DEVELOP_MONTH  |  3663K|    45M| 11994   (2)| 00:02:48 |
|*  7 |    HASH JOIN           |                       |     1 |    42 | 12762   (2)| 00:02:59 |
|*  8 |     TABLE ACCESS FULL  | TZZ_SJ_DEV_DISC_79073 | 21476 |   608K|   743   (2)| 00:00:11 |
|   9 |     TABLE ACCESS FULL  | TZZ_SJ_DEVELOP_MONTH  |  3663K|    45M| 11996   (2)| 00:02:48 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - filter("A2"."ALLO_DISC_TYPE_3" LIKE '%零预存%')
   7 - access("A1"."SERV_ID"="A2"."SERV_ID" AND "A1"."STAT_DATE"="A2"."STAT_DATE")
   8 - filter("A2"."ALLO_DISC_TYPE_3" LIKE '%租机%' AND LNNVL("A2"."ALLO_DISC_TYPE_3"
              LIKE '%零预存%'))

--表大小的情况:

OWNER                SEGMENT_NAME                   SEGMENT_TYPE           Size(Mb)
-------------------- ------------------------------ -------------------- ----------
GD_FS                TZZ_SJ_DEV_DISC_79073          TABLE                        43
GD_FS                TZZ_SJ_DEVELOP_MONTH           TABLE                   577.375

两个表并不大,一个43M,一个577M,这里肯定是开发者不小心,写错了语句,导致跑不出来。

AND "A2"."ALLO_DISC_TYPE_3" LIKE ‘%租机%‘  OR "A2"."ALLO_DISC_TYPE_3" LIKE ‘%零预存%‘;改成

AND ("A2"."ALLO_DISC_TYPE_3" LIKE ‘%租机%‘  OR "A2"."ALLO_DISC_TYPE_3" LIKE ‘%零预存%‘);

改动语句后,问题解决。

改写后:

SQL> explain plan for
  2  SELECT COUNT(*)
  3    FROM "GD_FS"."TZZ_SJ_DEV_DISC_79073" "A2",
  4         "GD_FS"."TZZ_SJ_DEVELOP_MONTH"  "A1"
  5   WHERE "A1"."SERV_ID" = "A2"."SERV_ID"
  6     AND "A1"."STAT_DATE" = "A2"."STAT_DATE"
  7     AND ("A2"."ALLO_DISC_TYPE_3" LIKE '%租机%' OR "A2"."ALLO_DISC_TYPE_3" LIKE '%零预存%');

Explained.

SQL> @getplan
'general,outline,starts'

Enter value for plan type:

PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------

Plan hash value: 3104770780

---------------------------------------------------------------------------------------------
| Id  | Operation           | Name                  | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |                       |     1 |    42 | 12765   (2)| 00:02:59 |
|   1 |  SORT AGGREGATE     |                       |     1 |    42 |            |          |
|*  2 |   HASH JOIN         |                       | 44081 |  1808K| 12765   (2)| 00:02:59 |
|*  3 |    TABLE ACCESS FULL| TZZ_SJ_DEV_DISC_79073 | 44081 |  1248K|   745   (3)| 00:00:11 |
|   4 |    TABLE ACCESS FULL| TZZ_SJ_DEVELOP_MONTH  |  3663K|    45M| 11996   (2)| 00:02:48 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("A1"."SERV_ID"="A2"."SERV_ID" AND "A1"."STAT_DATE"="A2"."STAT_DATE")
   3 - filter("A2"."ALLO_DISC_TYPE_3" LIKE '%租机%' OR "A2"."ALLO_DISC_TYPE_3" LIKE
              '%零预存%')
时间: 2024-10-21 22:44:52

OR导致笛卡尔积的相关文章

SQL笛卡尔积查询与关联查询性能对比

首先声明一下,sql会用略懂,不是专家,以下内容均为工作经验,聊以抒情. 今天帮忙验证同事发布的端口时,查看了一下相关sql内容,发现其使用的sql语句会导致笛卡尔积现象,为了帮其讲解进行了如下分析: student表: teacher表: course表: student_course表: 与发现问题类似的SQL1查询语句: SELECT d.st_name,d.class_id,d.st_id FROM course AS a, student_course AS b, teacher AS

阿里规范 - 五、MySQL 数据库 - (二)索引规约 - 10 - 【推荐】防止因字段类型不同造成的隐式转换,导致索引失效。

1.“列类型”与“where值类型”不符 2.join时 ① ② 相join的两个表的字符编码不同,不能命中索引,会导致笛卡尔积的循环计算(nested loop). 参考 : https://mp.weixin.qq.com/s/1Sowt2TcjMGDv55OQOe2rQ 原文地址:https://www.cnblogs.com/light-train-union/p/12222759.html

join时显示no join predicate原因分析以及解决办法

本位出处:http://www.cnblogs.com/wy123/p/6238844.html 最近遇到一个存储过程在某些特殊的情况下,效率极其低效, 至于底下到什么程度我现在都没有一个确切的数据,因为预期很快就可以查询出来结果的SQL,实则半个小时都出不来,后面会有截图 观察执行计划的时候发现中间有一步中出现一个类似如下非常规的连接提示警告,如下图 no join predicate 意思就是没有连接谓词,表之间join的时候没有指定连接谓词可以导致no join predicate, 但是

mysql知识点(三)

1.表关联是可以利用两个表的索引的,如果是用子查询,至少第二次查询是没有办法使用索引的. 2.  为了给主查询提供数据而首先执行的查询被叫做子查询 3.如果WHERE子句的查询条件里使用了函数(WHERE DAY(column) = …),MySQL也将无法使用索引. 4.多表查询没有指定连接条件,会导致笛卡尔积的出现,返回行数等于2张表的行数乘积,返回6行记录 已知表T1中有2行数据,T2中有3行数据,执行SQL语句,“select a.* from T1 a,T2 b”后,返回的行数为6(n

你真的了解“SQL”吗?《SQL优化最佳实践》作者带你重新了解SQL

一.SQL :一种熟悉又陌生的编程语言 这里有几个关键词:"熟悉"."陌生"."编程语言". 说它"熟悉",是因为它是DBA和广大开发人员,操作数据库的主要手段,几乎每天都在使用.说它"陌生",是很多人只是简单的使用它,至于它是怎么工作的?如何才能让它更高效的工作?却从来没有考虑过. 这里把SQL归结为一种"编程语言",可能跟很多人对它的认知不同.让我们看看它的简单定义(以下内容摘自百度

转 移动云基于MySQL Galera的PXC运维实战

https://mp.weixin.qq.com/s/YTwdVRh_Uhtf3bn2MO2H_Q 作者介绍 刘书浩,“移动云”DBA,负责“移动云”业务系统的数据库运维.标准化等工作:擅长MySQL技术领域,熟悉MySQL复制结构.Cluster架构及运维优化:具有自动化运维经验,负责“移动云”数据库管理平台的搭建. 前言 在众多的MySQL开源软件中,Galera是非常有特色的,它的特点及优势是具有良好的并发性和一致性.Galera Cluster的主要用途是为MySQL提供一致性的集群化解

使用express vpn导致国内网站无法访问的问题

一直在付费使用express vpn,网速很快. 但是最近发现一个问题,使用express vpnFQ之后,国外的网站访问正常,但是国内的网站却无法访问. 我的使用环境:win 10, 使用express vpn dns, expess vpn auto connect. 为了找到原因,在express vpn连接上的条件下,打开cmd窗口,依次ping baidu.com和163.com,结果为找不到域名对应的IP地址. 然后我再关闭express vpn连接,重新ping,发现IP地址解析正

android 2.x上Dialog特定情况导致无法dismiss的bug

近期在做一个简单的对话框框架,作用不过做出一个显示效果在android 2.x到android 4.x上均类似的对话框. 思路比較简单,就是使用装饰模式包裹Dialog,暴露的接口调用时会自己主动完毕一些设置 可是遇到一个特别诡异的问题,在android 2.x上的Dialog对话框无法被dismiss,仅仅要弹出来界面就卡死,强行使用eclipse又一次run的话会导致android设备黑屏无响应,假设是模拟器,则直接崩溃,看到启动画面.并且这个还不是ANR错误. 后来通过删减代码找到了问题的

静态变量导致的内存泄露

public  class MainActivity extends Activity{                private static final String TAG = "MainActivity";             private static Context sContext;                   @Override             protected void onCreate(Bundle savedInstanceState)