2009年3月4日 星期三

Write Java WebStart Application in 5 minutes

They say, the best way of learning is to do-it-yourself. When I was assigned to write an article on Java Webstart, I thought to truly understand what's happening with Java Web Start, let's create a program and try to deploy it through any web server.

Pre-requisities

  1. You need to have the latest version of JDK installed on your system before you can proceed. We use JDK 1.6. Here is a guide to install JDK 1.6 / Java SE 6 in Linux under 5 minutes.
  2. You will ideally need a source code editor like JEdit. At the least use notepad or vi (on *nix) to edit the source code. Do not use any word processing programs like Microsoft Word or Open Office Writer.
  3. Create a Java file that you want to run using JNLP. This can be a regular Swing or AWT based application. It can even be a console application if you wish.
  4. Compile and test your source code(s) as you would with a regular program.

Create a Jar file

Java Web Start applications need to be packaged within a jar file. You can create a .jar file from your class file(s) using this command (assume you class file is named Test.class):

   jar cvf test.jar Test.class
Note: v is for verbose mode. You can omit it if you want.

Create a key

You need to create a keystore which will then be used to sign the jar files:

      keytool -genkey -keystore myKeys -alias jdc

When prompted, fill in your name. You can skip the other details if you want.

Note: myKeys is the name of your keystore. You will need it in the next step to sign the jar file(s).

Now let's sign the jar file(s)

Run the command below to sign the jar file. When prompted for password, give it a six letter, easy to remember (just for demo not for production) password.

 jarsigner -keystore myKeys *.jar jdc

Create a JNLP file

jnlp

A JNLP file provides the specification for your Java Web Start application. We will not cover the details of a JNLP file in this brief guide. However we will provide you with a simple jnlp file which you can use for many occassions. JNLP file is in XML format. Use a source code editor to edit the file. Let's save it as test.jnlp on the document root of your local web server. You can use JWS, a simple web server that ships with Java Web Start, Apache, Tomcat or any other web server. The web server itself doesn't need any special capability to serve Java Web Start applications.

Note:

1. The main-class (test) is the main class of your application
2. We have used to allow the JNLP application to access all client resource. This is not something you may want to do in production environment. In production you should only ask for permissions that you really need to give customers peace of mind. Check the documentation of j2ee-application-client-permissions for details.

Create html file and run the baby!

Create a html file in the same location as the other files containing just the link to your jnlp file on your web server like say http://localhost/test.jnlp in this example. Now gather around your peers and boss (if you are feeling adventurous) and open the html file you just created in any browser. You will be prompted to open it in Java Web Start. Agree to it and also agree to any subsequent message asking you to grant permission to the application.

That's it guys! Wasn't that easy?


source: http://blog.taragana.com/

2009年3月1日 星期日

Oracle SQL裡常用的時間函數

Oracle SQL裡常用的時間函數,經典推薦

相信很多人都有過統計某些數據的經歷,比如,要統計財務的情況,可能要按每年,每季度,每月,甚至每個星期來分別統計。 那在oracle中應該怎麼來寫sql語句呢,這個時候Oracle的日期函數會給我們很多幫助。

常用日期型函數
1。 Sysdate當前日期和時間
SQL> Select sysdate from dual;

SYSDATE
----------
21-6月-05

2。 Last_day本月最後一天
SQL> Select last_day(sysdate) from dual;

LAST_DAY(S
----------
30-6月-05

3。 Add_months(d,n)當前日期d後推n個月用於從一個日期值增加或減少一些月份
date_value:=add_months(date_value,number_of_months)

SQL> Select add_months(sysdate,2) from dual;

ADD_MONTHS
----------
21-8月-05

4。 Months_between(f,s)日期f和s間相差月數
SQL> select months_between(sysdate,to_date('2005-11-12','yyyy-mm-dd'))from dual;

MONTHS_BETWEEN(SYSDATE,TO_DATE('2005-11-12','YYYY-MM-DD'))
-------------------------------------------------- --------
-4.6966741

5。 NEXT_DAY(d, day_of_week)
返回由"day_of_week"命名的,在變量"d"指定的日期之後的第一個工作日的日期。 參數"day_of_week"必須為該星期中的某一天。
SQL> SELECT next_day(to_date('20050620','YYYYMMDD'),1) FROM dual;

NEXT_DAY(T
----------
26-6月-05

6。 current_date()返回當前會話時區中的當前日期
date_value:=current_date
SQL> column sessiontimezone for a15
SQL> select sessiontimezone,current_date from dual;

SESSIONTIMEZONE CURRENT_DA
--------------- ----------
+08:00 13-11月-03


SQL> alter session set time_zone='-11:00' 2 /
會話已更改。

SQL> select sessiontimezone,current_timestamp from dual;

SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ----------------------------------- -
-11:00 12-11月-03 04.59.13.668000下午-11:00

7。 current_timestamp()以timestamp with time zone數據類型返回當前會話時區中的當前日期
SQL> select current_timestamp from dual;

CURRENT_TIMESTAMP
-------------------------------------------------- -------------------------
21-6月-05 10.13.08.220589上午+08:00

8。 dbtimezone()返回時區
SQL> select dbtimezone from dual;

DBTIME
------
-08:00

9。 extract()找出日期或間隔值的字段值
date_value:=extract(date_field from [datetime_value|interval_value])
SQL> select extract(month from sysdate) "This Month" from dual;

This Month
----------
6

SQL> select extract(year from add_months(sysdate,36)) " Years" from dual;

Years
----------
2008

10。 localtimestamp()返回會話中的日期和時間
SQL> select localtimestamp from dual;

LOCALTIMESTAMP
-------------------------------------------------- -------------------------
21-6月-05 10.18.15.855652上午

11。取得week number
TO_CHAR(TO_DATE('2007/05/16','YYYY/MM/DD'),'IW') AS WEEK




常用日期數據格式(該段為摘抄)

Y或YY或YYY年的最後一位,兩位或三位Select to_char(sysdate,’YYY’) from dual; 002表示2002年
SYEAR或YEAR SYEAR使公元前的年份前加一負號Select to_char(sysdate,’SYEAR’) from dual; -1112表示公元前111 2年
Q季度,1~3月為第一季度Select to_char(sysdate,’Q’) from dual; 2表示第二季度①
MM月份數Select to_char(sysdate,’MM’) from dual; 12表示12月
RM月份的羅馬錶示Select to_char(sysdate,’RM’) from dual; IV表示4月
Month用9個字符長度表示的月份名Select to_char(sysdate,’Month’) from dual; May後跟6個空格表示5月
WW當年第幾週Select to_char(sysdate,’WW’) from dual; 24表示2002年6月13日為第24週
W本月第幾週Select to_char(sysdate,’W’) from dual; 2002年10月1日為第1週
DDD當年第幾, 1月1日為001,2月1日為032 Select to_char(sysdate,’DDD’) from dual; 363 2002年1 2月2 9日為第363天
DD當月第幾天Select to_char(sysdate,’DD’) from dual; 04 10月4日為第4天
D週內第幾天Select to_char(sysdate,’D’) from dual; 5 2002年3月14日為星期一
DY週內第幾天縮寫Select to_char(sysdate,’DY’) from dual; SUN 2002年3月24日為星期天
HH或HH12 12進制小時數Select to_char(sysdate,’HH’) from dual; 02午夜2點過8分為02
HH24 24小時制Select to_char(sysdate,’HH24’) from dual; 14下午2點08分為14
MI分鐘數(0~59) Select to_char(sysdate,’MI’) from dual; 17下午4點17分
SS秒數(0~59) Select to_char(sysdate,’SS’) from dual; 22 11點3分22秒提示注意不要將MM格式用於分鐘(分鐘應該使用MI)。 MM是用於月份的格式,將它用於分鐘也能工作,但結果是錯誤的。


現在給出一些實踐後的用法:

1。 上月末天:
SQL> select to_char(add_months(last_day(sysdate),-1),'yyyy-MM-dd') LastDay from dual;

LASTDAY
----------
2005-05-31

2。 上月今天
SQL> select to_char(add_months(sysdate,-1),'yyyy-MM-dd') PreToday from dual;


PRETODAY
----------
2005-05-21

3.上月首天
SQL> select to_char(add_months(last_day(sysdate)+1,-2),'yyyy-MM-dd') firstDay from dual;

FIRSTDAY
----------
2005-05-01

4.按照每週進行統計
SQL> select to_char(sysdate,'ww') from dual group by to_char(sysdate,'ww');

TO
--
25

5。 按照每月進行統計
SQL> select to_char(sysdate,'mm') from dual group by to_char(sysdate,'mm');

TO
--
06

6。 按照每季度進行統計
SQL> select to_char(sysdate,'q') from dual group by to_char(sysdate,'q');

T
-
2

7。 按照每年進行統計
SQL> select to_char(sysdate,'yyyy') from dual group by to_char(sysdate,'yyyy');

TO_C
----
2005

8.要找到某月中所有周五的具體日期
select to_char(td,'YY-MM-DD') from (
select trunc(sysdate, 'MM')+rownum-1 as d
from dba_objects
where rownum <>

and trim(to_char(td, 'Day')) = '星期五'
--------
03-05-02
03-05-09
03-05-16
03-05-23
03-05-30

如果把where to_char(td, 'MM') = to_char(sysdate, 'MM')改成sysdate-90,即為查找當前月份的前三個月中的每週五的日期。

9.oracle中時間運算

內容如下:
1、oracle支持對日期進行運算
2、日期運算時是以天為單位進行的
3、當需要以分秒等更小的單位算值時,按時間進制進行轉換即可
4、進行時間進制轉換時注意加括號,否則會出問題

SQL> alter session set nls_date_format='yyyy-mm-dd hh:mi:ss';

會話已更改。

SQL> set serverout on
SQL> declare
2 DateValue date;
3 begin
4 select sysdate into DateValue from dual;
5 dbms_output.put_line('原時間:'||to_char(DateValue));
6 dbms_output.put_line('原時間減1天:'||to_char(DateValue-1));
7 dbms_output.put_line('原時間減1天1小時:'||to_char(DateValue-1-1/24));
8 dbms_output.put_line('原時間減1天1小時1分:'||to_char(DateValue-1-1/24-1/(24*60)));
9 dbms_output.put_line('原時間減1天1小時1分1秒:'||to_char(DateValue-1-1/24-1/(24*60)-1/(24*60*60))) ;
10 end;
11 /
原時間:2003-12-29 11:53:41
原時間減1天:2003-12-28 11:53:41
原時間減1天1小時:2003-12-28 10:53:41
原時間減1天1小時1分:2003-12-28 10:52:41
原時間減1天1小時1分1秒:2003-12-28 10:52:40

PL/SQL過程已成功完成。


在Oracle中實現時間相加處理
--名稱:Add_Times
--功能:返回d1與NewTime相加以後的結果,實現時間的相加
--說明:對於NewTime中的日期不予考慮
--日期:2004-12-07
--版本:1.0
--作者:Kevin


create or replace function Add_Times(d1 in date,NewTime in date) return date
is
hh number;
mm number;
ss number;
hours number;
dResult date;
begin
--下面依次取出時、分、秒
select to_number(to_char(NewTime,'HH24')) into hh from dual;
select to_number(to_char(NewTime,'MI')) into mm from dual;
select to_number(to_char(NewTime,'SS')) into ss from dual;
--換算出NewTime中小時總和,在一天的百分幾
hours := (hh + (mm / 60) + (ss / 3600))/ 24;
--得出時間相加後的結果
select d1 + hours into dResult from dual;
return(dResult);
end Add_Times;


--測試用例
-- select Add_Times(sysdate,to_date('2004-12-06 03:23:00','YYYY-MM-DD HH24:MI:SS')) from dual


在Oracle9i中計算時間差計算時間差是Oracle DATA數據類型的一個常見問題。 Oracle支持日期計算,你可以創建諸如“日期1-日期2”這樣的表達式來計算這兩個日期之間的時間差。


一旦你發現了時間差異,你可以使用簡單的技巧來以天、小時、分鐘或者秒為單位來計算時間差。 為了得到數據差,你必須選擇合適的時間度量單位,這樣就可以進行數據格式隱藏。

使用完善複雜的轉換函數來轉換日期是一個誘惑,但是你會發現這不是最好的解決方法。

round(to_number(end-date-start_date))-消逝的時間(以天為單位)

round(to_number(end-date-start_date)*24)-消逝的時間(以小時為單位)

round(to_number(end-date-start_date)*1440)-消逝的時間(以分鐘為單位)

顯示時間差的默認模式是什麼? 為了找到這個問題的答案,讓我們進行一個簡單的SQL *Plus查詢。

SQL> select sysdate-(sysdate-3) from dual;

SYSDATE-(SYSDATE-3)
-------------------
3

這裡,我們看到了Oracle使用天來作為消逝時間的單位,所以我們可以很容易的使用轉換函數來把它轉換成小時或者分鐘。 然而,當分鐘數不是一個整數時,我們就會遇到放置小數點的問題。

Select
(sysdate-(sysdate-3.111))*1440
from
dual;

(SYSDATE-(SYSDATE-3.111))*1440
------------------------------
4479.83333

當然,我們可以用ROUND函數(即取整函數)來解決這個問題,但是要記住我們必須首先把DATE數據類型轉換成NUMBER數據類型。

Select
round(to_number(sysdate-(sysdate-3.111))*1440)
from
dual;

ROUND(TO_NUMBER(SYSDATE-(SYSDATE-3.111))*1440)
----------------------------------------------
4480

我們可以用這些函數把一個消逝時間近似轉換成分鐘並把這個值寫入Oracle表格中。 在這個例子裡,我們有一個離線(logoff)系統級觸發機制來計算已經開始的會話時間並把它放入一個Oracle STATSPACK USER_LOG擴展表格之中。

Update
perfstat.stats$user_log
set
elapsed_minutes =
round(to_number(logoff_time-logon_time)*1440)
where
user = user_id
and
elapsed_minutes is NULL;

查出任一年月所含的工作日
CREATE OR REPLACE FUNCTION Get_WorkingDays(
ny IN VARCHAR2
) RETURN INTEGER IS
/*------------------------------------------------ ------------------------------------------
函數名稱:Get_WorkingDays
中文名稱:求某一年月中共有多少工作日作者姓名: XINGPING
編寫時間: 2004-05-22
輸入參數:NY:所求包含工作日數的年月,格式為yyyymm,如200405
返回值:整型值,包含的工作日數目。
算法描述:
1).列舉出參數給出的年月中的每一天。 這裡使用了一個表(ljrq是我的庫中的一張表。這個表可以是有權訪問的、記錄條數至少為31的任意一張表或視圖)來構造出某年月的每一天。
2).用這些日期和一個已知星期幾的日期相減(2001-12-30是星期天),所得的差再對7求模。 如果所求年月在2001-12-30以前,那麼所得的差既是負數,求模後所得值範圍為大於-6,小於0,如-1表示星期六,故先將求模的結果加7,再求7的模.
3).過濾掉結果集中值為0和6的元素,然後求count,所得即為工作日數目。
-------------------------------------------------- -----------------------------------------------*/
Result INTEGER;
BEGIN
SELECT COUNT(*) INTO Result
FROM (SELECT MOD(MOD(q.rq-to_date('2001-12-30','yyyy-mm-dd'),7),7) weekday
FROM ( SELECT to_date(ny||t.dd,'yyyymmdd') rq
FROM (SELECT substr(100+ROWNUM,2,2) dd
FROM ljrq z WHERE Rownum<=31 ) t WHERE to_date(ny||t.dd,'yyyymmdd') BETWEEN to_date(ny,'yyyymm') AND last_day(to_date(ny,'yyyymm')) )q ) a WHERE a.weekday NOT IN(0,6); RETURN Result; END Get_WorkingDays;

______________________________________

還有一個版本
CREATE OR REPLACE FUNCTION Get_WorkingDays(
ny IN VARCHAR2
) RETURN INTEGER IS
/*------------------------------------------------ -----------------------------------------
函數名稱:Get_WorkingDays
中文名稱:求某一年月中共有多少工作日作者姓名: XINGPING
編寫時間: 2004-05-23
輸入參數:NY:所求包含工作日數的年月,格式為yyyymm,如200405
返回值:整型值,包含的工作日數目。
算 法描述:使用Last_day函數計算出參數所給年月共包含多少天,根據這個值來構造一個循環。 在這個循環中先求這個月的每一天與一個已知是星期天的日期(2001-12-30是星期天)的差,所得的差再對7求模。 如果所求日期在2001-12-30以前,那麼所得的差既是負數,求模後所得值範圍為大於-6,小於0,如-1表示星期六,故先將求模的結果加7,再求7 的模.如過所得值不等於0和6(即不是星期六和星期天),則算一個工作日。
-------------------------------------------------- --------------------------------------*/
Result INTEGER := 0;
myts INTEGER; --所給年月的天數
scts INTEGER; --某天距2001-12-30所差的天數
rq DATE;
djt INTEGER := 1; --
BEGIN
myts := to_char(last_day(to_date(ny,'yyyymm')),'dd');
LOOP
rq := TO_date(ny||substr(100+djt,2),'yyyymmdd');
scts := rq - to_date('2001-12-30','yyyy-mm-dd');
IF MOD(MOD(scts,7)+7,7) NOT IN(0,6) THEN
Result := Result + 1;
END IF;
djt := djt + 1;
EXIT WHEN djt>myts;
END LOOP;
RETURN Result;
END Get_WorkingDays;

以上兩個版本的比較

第一個版本一條SQL語句就可以得出結果,不需要編程就可以達到目的。 但需要使用任意一張有權訪問的、記錄條數至少為31的一張表或視圖。
第二個版本需要編程,但不需要表或者視圖。
這兩個版本都還存在需要完善的地方,即沒有考慮節日,如五一、十一、元旦、春節這些節假期都沒有去除。 這些節假日應該維護成一張表,然後通過查表來去除這些節假日。

求一段連續日期,但排除六日
自已標記一下,方便以後查尋

select allday from (
select to_date('2007-02-15','yyyy-mm-dd')+rownum allday from
(select to_date('2007-02-15','yyyy-mm-dd'),to_date('2007-02-28','yyyy-mm-dd') from dual)
connect by rownum <>1 and to_char(allday,'D') <7>



source: http://oracled2k.pixnet.net/blog

2009年2月4日 星期三

The differences between Truncate, Delete and Drop

Truncate, Delete, Drop的異同點

注意:這裡說的delete是指不帶where子句的delete語句

相同點
truncate和不帶where子句的delete,以及drop都會刪除表內的數據

不同點:
1. truncate和delete只刪除數據不刪除表的結構(By Definition)
drop語句將刪除表的結構被依賴的約束(constrain),觸發器(trigger),索引(index);依賴於該表的存儲過程/函數將保留,但是變為invalid狀態.

2.delete語句是dml,這個操作會放到rollback segement中,事務提交之後才生效;如果有相應的trigger,執行的時候將被觸發.
truncate,drop是ddl,操作立即生效,原數據不放到rollback segment中,不能回滾.操作不觸發trigger.

3.delete語句不影響表所佔用的extent,高水線(high watermark)保持原位置不動
顯然drop語句將表所佔用的空間全部釋放 ;
truncate語句缺省情況下見空間釋放到minextents個extent,除非使用reuse storage; truncate會將高水線復位(回到最開始).
4.速度,一般來說: drop>; truncate >; delete
5.安全性:小心使用drop和truncate,尤其沒有備份的時候.否則哭都來不及
使用上,想刪除部分數據行用delete,注意帶上where子句.回滾段要足夠大.
想刪除表,當然用drop
想保留表而將所有數據刪除.如果和事務無關,用truncate即可.如果和事務有關,或者想觸發trigger,還是用delete.
如果是整理表內部的碎片,可以用truncate跟上reuse stroage,再重新導入/插入數據

事務中的DDL語句會引起COMMIT的, Truncate是不會全部釋放存儲空間!
Drop會釋放存儲空間!

Source: http://bbs.chinaunix.net/viewthread.php?tid=252763

2009年1月29日 星期四

權限設計參考

遲d整理, 睇住先
http://www.cnblogs.com/a7345678/archive/2008/09/25/1298838.html
http://www.blogjava.net/amigoxie/archive/2007/09/29/149509.html
http://www.cnblogs.com/yukaizhao/archive/2007/04/15/user_role_action_permission.html
http://www.blogjava.net/RongHao/category/20773.html

2009年1月20日 星期二

DBCP, C3P0常用參數,和使用中碰到的問題

DBCP:
driverClassName
url
username
password
上面四個分別是驅動,連接字符串,用戶名和密碼

maxActive連接池支持的最大連接數
maxIdle連接池中最多可空閒maxIdle個連接
minIdle連接池中最少空閒maxIdle個連接
initialSize初始化連接數目
maxWait連接池中連接用完時,新的請求等待時間,毫秒
timeBetweenEvictionRunsMillis timeBetweenEvictionRunsMillis和minEvictableIdleTimeMillis一起使用,每

timeBetweenEvictionRunsMillis毫秒秒檢查一次連接池中空閒的連接,把空閒時間超過minEvictableIdleTimeMillis毫秒的連接斷開,直到連接池中的連接數到minIdle為止

minEvictableIdleTimeMillis連接池中連接可空閒的時間,毫秒

removeAbandoned true,false,是否清理removeAbandonedTimeout秒沒有使用的活動連接,清理後並沒有放回連接池
removeAbandonedTimeout活動連接的最大空閒時間
logAbandoned true,false,連接池收回空閒的活動連接時是否打印消息


minEvictableIdleTimeMillis,removeAbandonedTimeout這兩個參數針對的連接對像不一樣,minEvictableIdleTimeMillis針對連接池中的連接對象,removeAbandonedTimeout針對未被close的活動連接.

在dbcp使用中遇到的問題:
當短時間之內活動連接達到maxActive,再請求連接,等maxWait秒後連接池就會報出錯來:Cannot get a connection, pool exhausted.在這maxWait秒裡removeAbandoned並沒有起作用,出錯後連接池就會把所有的連接斷開,為什麼這時候 removeAbandoned沒有起作用呢?


C3P0:
http://sourceforge.net/projects/c3p0 (c3p0-src - c3p0-0.9.1.2)
driverClass
jdbcUrl
user
password
minPoolSize
maxPoolSize
initialPoolSize

acquireIncrement池中沒有空閒連接時,一次請求獲取的連接數
maxIdleTime池中連接最大空閒時間
acquireRetryAttempts獲取連接失敗後,重新嘗試的次數
acquireRetryDelay嘗試連接間隔時間,毫秒
checkoutTimeout等待連接時間,0為無限等待,毫秒
DebugUnreturnedConnectionStackTraces true,false,是否收回未返回的活動連接
unreturnedConnectionTimeout活動連接的時間.

c3p0中的問題:
unreturnedConnectionTimeout是給每個活動連接一個時間限制,到點兒就收回,不管有沒有正在使用連接.這樣不是太好,應該是從最後一次使用連接才開始計時才好.那有沒有這樣的一個參數從最後一次使用計時呢?

source:
http://www.javaeye.com/post/607253
http://www.hibernate.org/214.html
For C3P0
http://www.hibernate.org/214.html?cmd=comphist&histnode=1059

2009年1月18日 星期日

SQL指定時間段的查詢

表名:A
時間字段:ddatetime(datetime類型)

查詢2003-2004年6月7日-7月8日數據。

select * from A where (extract(year from ddatetime) between 2003 and 2004)
and (extract(month from ddatetime) between 6 and 7)
and (extract(day from ddatetime) between 6 and 7)

extract只能取到日。小時,或者到秒,需要to_char。

查詢2003-2004年6月7日-7月8日12時到20時數據。

select * from A where (extract(year from ddatetime) between 2003 and 2004)
and (extract(month from ddatetime) between 6 and 7)
and (extract(day from ddatetime) between 6 and 7) and (to_char(ddatetime,'HH24') between 12 and 20)

以上查詢在oracle可運行。

2009年1月7日 星期三

Oracle中的 IN, NOT IN和 EXISTS, NOT EXISTS的區別

通常聽到的都是說盡量用exists不要用in,因為exists只判斷存在而in需要對比值,所以exists比較快,但看了看網上的一些東西才發現根本不是這麼回事。
下面這段是抄的
Select * from T1 where x in ( select y from T2 )
執行的過程相當於:
select *
from t1, ( select distinct y from t2 ) t2
where t1.x = t2.y;

select * from t1 where exists ( select null from t2 where y = x )
執行的過程相當於:
for x in ( select * from t1 )
loop
if ( exists ( select null from t2 where y = x.x )
then
OUTPUT THE RECORD
end if
end loop

從我的角度來說,in的方式比較直觀,exists則有些繞,而且in可以用於各種子查詢,而exists好像只用於關聯子查詢(其他子查詢當然也可以用,可惜沒意義)。
由於exists是用loop的方式,所以,循環的次數對於exists影響最大,所以,外表要記錄數少,內表就無所謂了,而in用的是hash join,所以內表如果小,整個查詢的範圍都會很小; 如果內表很大,外表如果也很大就很慢了,這時候exists才真正的會快過in的方式。


Not in和Not exists
如果查詢語句使用了not in那麼內外表都進行全表掃描,沒有用到索引;
而not extsts的子查詢依然能用到表上的索引。
所以無論那個表大,用not exists都比not in要快。
也就是說,in和exists需要具體情況具體分析,not in和not exists就不用分析了,盡量用not exists就好了。

source:http://www.blogjava.net/wphmoon