在客商迁移测试时,程序一旦开始执行就不能自动停止。只能通过手动中断应用服务器的进程来停止。检查迁移的一个表,这个表迁移前没有数据,迁移最多会插入3w条左右数据,但是迁移过程执行2个多小时候再看,已经有32G了。
  首先,这个表没有blob等大对象字段,按正常情况肯定不会占用32G空间。因为整个迁移过程是一个事务,迁移不结束无法查看这个表的真实行数。这个时候怀疑程序有死循环。
开发在联测代码时,发现下面这个SQL,第一次查询后,后面不管第几次查都跟第一次结果一样,这也就是导致死循环的原因。
下面看下这个SQL:
select pk_cubasdoc
from (select row_number() over(order by PK_CUBASDOC asc) rn, pk_cubasdoc
from src_cubasdoc
where 1 = 1
and (iscustomer = 'Y' and issupplier = 'Y')
or (iscustomer = '~' and issupplier = '~')
and pk_cubasdoc > '1006A3100000000YB5CP') tablewithrn
where tablewithrn.rn < 20001;
src_cubasdoc这个表有26917行记录,并且取出的数据插入到表itf_customer。
  虽然这条SQL的本意是,想在取出前2w条记录的基础上,循环取出后6917行数据。而pk_cubasdoc='1006A3100000000YB5CP'正是第2w条记录。但是结果呢,却总是取出来前2w行记录,无穷无尽成了死循环。
  为什么会成为死循环?对,是and和or优先级问题。既然要取后2w行记录,那么肯定是先对表src_cubasdoc条件过滤后再取pk_cubasdoc>'1006A3100000000YB5CP'的记录。
现在的SQL却是按and (iscustomer = 'Y' and issupplier = 'Y') or ((iscustomer = '~' and issupplier = '~') and pk_cubasdoc > '1006A3100000000YB5CP'))的执行顺序。这样就跟是否pk_cubasdoc的条件关系不大了。也就是说按目前这种写法首先根本不是原意,还有一种副作用,就是怎么取都是前2w行。
  将SQL修改为:
 select pk_cubasdoc
from (select row_number() over(order by PK_CUBASDOC asc) rn, pk_cubasdoc
from src_cubasdoc
where 1 = 1
and ((iscustomer = 'Y' and issupplier = 'Y')
or (iscustomer = '~' and issupplier = '~'))
and pk_cubasdoc > '1006A3100000000YB5CP') tablewithrn
where tablewithrn.rn < 20001;
整个迁移过程不到10分钟结束。
这个SQL就是or前后没有加括号导致的问题。
写SQL时一定要注意,使用or时,一定要注意or的优先级没有and的高,如果先执行or必须将or前后子句加括号。

由 OR 引起的死循环的更多相关文章

  1. scanf类型不匹配造成死循环

        int i = 0; while (flag) { printf("please input a number >>> "); scanf("% ...

  2. 如何决解项目中hibernate中多对多关系中对象转换json死循环

    先写一下原因吧!我是写的SSH项目,在项目中我遇到的问题是把分页对象(也就是pageBean对象)转化为json数据,下面为代码: public class PageBean <T>{// ...

  3. nginx $document_uri 防止死循环

    $document_uri 表示访问的url 现在我的需求是,访问 www.xxx.com 请求到 www.xxx.com/bbs/ 在nginx配置文件中加入 if ($document_uri ! ...

  4. 加载默认图片,如何避免img标签陷入onerror事件死循环

    当图片加载失败的时候,我们可以利用onerror事件赋予它默认图片,但是问题来了,假如默认图片又不存在呢,即加载失败,这个时候就会陷入死循环. 为了避免死循环的情况,我们可以在执行完onerror事件 ...

  5. json死循环问题

    20.JSON死循环问题: 向前台发送的数据: 出现此类问题主要是由于在所传数据中有包含关系,比如ElementGroup中有Element,Element中又有ElementGroup,此时就会出现 ...

  6. STM32的USART中断死循环,形成死机。

    作者:观海  QQ:531622 直接说重点:我用的是 STM32F103 芯片 USART2_IRQHandler 总是中断,程序死循环. 1.出现问题: 原程序的中断处理程序是: void USA ...

  7. scanf_s 可能会出现的死循环

                                        VS2015中提供了scanf_s().在调用时,必须提供一个数字以表明最多读取多少位字符. scanf_s("%s& ...

  8. 调试 zeromq 发现 accept 死循环

    起因:在群里一个同学说使用 zeromq 的时候出了点儿问题,问题描述如下“router连接十几万客户端后,然后把router杀死,重启,这时候zeromq的某个线程99%的cpu,卡死了,再也接受不 ...

  9. 由一个RABBITMQ监听器死循环引出的SPRING中BEAN和MAPPER接口的注入问题

    1 @Slf4j 2 @RestController 3 @Component 4 public class VouchersReceiverController implements Message ...

  10. 如何定位死循环或高CPU使用率(linux)

    如何定位死循环或高CPU使用率(linux)  确定是CPU过高 使用top观察是否存在CPU使用率过高现象 找出线程 对CPU使用率过高的进程的所有线程进行排序 ps H -e -o pid,tid ...

随机推荐

  1. MonkeyRunner源码分析之工作原理图

    http://www.androidchina.net/1315.html

  2. Linux系列:Ubuntu虚拟机设置固定IP上网(配置IP、网关、DNS、防止resolv.conf被重写)

    虚拟机里设置上网方式为NAT最方便,因为无需手动设置即可上网,但是NAT的上网方式默认是DHCP动态分配IP的,这意味着你每次重启虚拟机都 有不一样的IP地址,这对一般用户没任何问题.但是如果你的机子 ...

  3. [React] React Fundamentals: Component Lifecycle - Mounting Basics

    React components have a lifecycle, and you are able to access specific phases of that lifecycle. Thi ...

  4. 使用DrawerLayout实现侧拉菜单

    侧拉菜单在android应用中非常常见,它的实现方式太多了,今天我们就说说使用Google提供的DrawerLayout来实现侧拉菜单效果,先来看张效果图: DrawerLayout的实现其实非常简单 ...

  5. js按值传递还是按引用传递?

    js和其他大部分语言一样,有基本类型和引用类型.因此访问变量就有按值和按引用两种方式,但是传参的时候却只能按值传递.基本类型作为参数时按值传递自然无可厚非,但引用类型作为参数也按值传递就让人有点困惑了 ...

  6. Asp.Net分页存储过程

      SQL分页语句 一.比较万能的分页: sql代码: 1 2 3 select top 每页显示的记录数 * from topic where id not in  (select top (当前的 ...

  7. Linux 下mysql忘记root密码解决方法

    忘记root密码怎么办:1.关闭数据库2.使用-->mysqld_safe --skip-grant-tables &--<启动数据库3.使用空密码进入数据库(mysql命令后直接 ...

  8. Web Services之SOAP学习

    Web Services之SOAP [toc] 什么是SOAP SOAP(Simple Object Access Protocol)简单对象访问协议是在分散或分布式的环境中交换信息的简单的协议,是一 ...

  9. SSIS结合BCP及SQL Server作业实现定时将数据导出打包实现数据同步

    首先这个流程要实现的功能大致是: 有两台服务器,一台是对外网开发的,一台是内网的.那么很明显数据交互都是外网服务器在做,而这个流程要做的就是要将外网上面的数据定时同步到内网中. 我们依对其中某张表的操 ...

  10. Linq 与UnitOfWork

    submitchages(linq to sql)或者savechanges(ef)的次数是根据你操作方法的数量决定的,也即是:它只认识自己的提交语句(submtchanges,savechanges ...