oracle exists与in并不能互用

oracle exists并发

前些天仔细研究了下oracle exists与in的区别。经过深层次的分析后发现exists与in并不能互用。

先谢谢@Elvis_dataguru文章的详细解说,我基于他基础上做详细分析后总结如下:

  1. exists的解释:“Exists只能用于子查询,若匹配到一条结果,子查询中断,并将条件标志为true”。

  2. in的解释“in不管匹配到匹配不到都全部匹配完毕”。

此文并非比较exists与in的区别,或者讨论两者的效率,或者两者互用的注意事项,此类文章在百度、google上都有很多解释。而正如@Elvis_dataguru,大家都认为exists与in能够在一定程度上互用。

以下是我分析的过程:

  1. 数据表结构(n条数据)

     

    table user (
          userNo varchar2(10) not null,
          userType varchar2(1) not null
    )

  2. 操作语句

     操作语句1

    update user t set t.userType = $USER_TYPE_NEW$ where t.userType <> $USER_TYPE_OLD$
    操作语句2
    update user t set t.userType = $USER_TYPE_NEW$ where exists(select 1 from user tt where tt.userType <> $USER_TYPE_OLD$)

    sql语句说明:如果userType不是USER_TYPE_OLD则更新为USER_TYPE_NEW。以上是我分别测试的两个sql语句。两个sql语句最终目的是一样的。

  3. 操作代码

     

    for (;;) {
    	Map<String, Integer> map1 = new HashMap<String, Integer>();
    	map1.put("USER_TYPE_NEW", 2);//修改成的参数(new的参数)	
    	map1.put("USER_TYPE_OLD", 1);//old的参数
    	Thread t1 = new Thread(new Test2(map1));
    	Map<String, Integer> map2 = new HashMap<String, Integer>();
    	map2.put("USER_TYPE_NEW", 1);//修改成的参数(new的参数)
    	map2.put("USER_TYPE_OLD", 2);//old的参数
    	Thread t2 = new Thread(new Test2(map2));
    	t1.start();
    	t2.start();
    	t1.join();
    	t2.join();
    	int i = map1.get("SUM_COUNT");// 更新的条数
    	int j = map2.get("SUM_COUNT");// 更新的条数
    	System.out.println("MAP1(2,1) 的值是:" + i);
    	System.out.println("MAP2(1,2) 的值是:" + j);
    	if (i != 0 && j != 0) {
    		// 如果更新条数有一个不为0。则将数据还原后继续执行。
    		Map<String, Integer> map3 = new HashMap<String, Integer>();
    		map3.put("USER_TYPE_NEW", 0);//原始值
    		map3.put("USER_TYPE_OLD", 3);//其他确定不等于的任意值
    		Thread t3 = new Thread(new Test2(map3));
    		t3.start();
    		t3.join();
    	} else {
    		// 如果更新条数一样。将直接结束循环。
    		break;
    	}
    }
    java代码说明:传入修改的内容。USER_TYPE_NEW对应sql中$USER_TYPE_NEW$参数,USER_TYPE_OLD对应sql中$USER_TYPE_OLD$参数。先启动两个线程,分别调用Test2执行sql语句。将update影响的行数返回,分别是i和j。如果i和j都不等于0,则将数据还原继续循环执行。

  4. 操作结果

     操作语句1执行结果:在应用开始执行后一直执行下去(跑一晚上,执行次数未知,语句1写的是“<>”,我同样测试过了“in”的情况,结果是一样的,不分开说明了)。i等于0或者n。j等于n或者0。当i等于0时,j等于n;当i等于n时,j等于0。

             操作语句2执行结果:在应用开始执行后10秒左右后(执行几十次的平均值)。i等于n,j同时也等于n,跳出for循环后服务停止运行。


以上总结:

1.in在oracle内处理了并发,而exists在一定并发下存在问题。可能正是因为exists只检查是否有记录后返回true的缘故,此问题我查阅了大量的oracle文献也未得到相关的说明。

2.exists子句前面的update和后面的子查询分开执行,在oracle执行exists子句后,update时将不再判断exists子句是否为真。此结果可以从执行操作语句2时i和j的值相等得来(如果会判断,结果应该是i + j = n)。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页