Java && C#

          要學(xué)得東西很多,但我們的時(shí)間卻不是很多!
          數(shù)據(jù)加載中……
          SQL執(zhí)行效率

          SQL語(yǔ)句中,IN、EXISTS、NOT IN、NOT EXISTS的效率較低,尤其是后兩種語(yǔ)句,當(dāng)數(shù)據(jù)量較大時(shí),更常給人一種死機(jī)般的感覺(jué)。本文提供一種使用連接的方法代替以上的四種語(yǔ)句,可大副提高SQL語(yǔ)句的運(yùn)行效率。以NOT IN為例,當(dāng)數(shù)據(jù)量達(dá)到一萬(wàn)時(shí),效率可提高20倍,數(shù)據(jù)量越大,效率提高的幅度也就越大。

          本文所舉的例子在Oracle 7.0下運(yùn)行通過(guò),但本文所推薦的方法在各種大型數(shù)據(jù)庫(kù)上皆適用。
          為了能夠更好的說(shuō)明問(wèn)題,我們采用示例的方式來(lái)說(shuō)明問(wèn)題。下面,我們將創(chuàng)建一些數(shù)據(jù)庫(kù)表和數(shù)據(jù),用于在舉例時(shí)使用。

          下面的語(yǔ)句將創(chuàng)建我們示例中將使用的表,并分別在表1(TAB1)中存入10000條數(shù)據(jù),表2(TAB2)中存入5000條數(shù)據(jù)。

          SQL語(yǔ)句如下:

          CREATE TABLE TAB1
          (
          COL1 VARCHAR(20) NOT NULL,
          COL2 INTEGER,
          PRIMARY KEY(COL1)
          );
          CREATE TABLE TAB2
          (
          COL1 VARCHAR(20) NOT NULL,
          PRIMARY KEY(COL1)
          );
          CREATE TABLE TAB3
          (
          COL1 VARCHAR(20) NOT NULL,
          PRIMARY KEY(COL1)
          );
          CREATE OR REPLACE TRIGGER T_TAB3 BEFORE INSERT ON TAB3 FOR EACH ROW
          DECLARE
          NUM1 NUMBER;
          BEGIN
          NUM1:=1;
          LOOP
          EXIT WHEN NUM1>10000;
          INSERT INTO TAB1 VALUES (NUM1,NUM1);
          IF NUM1<=5000 THEN INSERT INTO TAB2 VALUES (NUM1);
          END IF;
          NUM1:=NUM1+1;
          END LOOP;
          END;
          INSERT INTO TAB3 VALUES('1');

          下面,我們將舉2個(gè)例子來(lái)具體說(shuō)明使用連接替換IN、NOT IN、EXISTS、NOT EXISTS的方法。

           讀取表1中第2列(COL2)數(shù)據(jù)的總和,且其第1列數(shù)據(jù)存在于表2的第1列中。

          1. 使用IN的SQL語(yǔ)句:

          SELECT SUM(COL2) FROM TAB1 WHERE COL1 IN(SELECT COL1 FROM TAB2)

          2. 使用EXISTS的SQL語(yǔ)句:

          SELECT SUM(COL2) FROM TAB1 WHERE EXISTS(SELECT * FROM TAB2 WHERE TAB1.COL1=TAB2.COL1)

          3. 使用連接的SQL語(yǔ)句:

          SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B

          WHERE A.COL1=B.COL1

           讀取表1中第2列(COL2)數(shù)據(jù)的總和,且其第1列數(shù)據(jù)不存在于表2的第1列中。


          1. 使用NOT IN的SQL語(yǔ)句:

          SELECT SUM(COL2) FROM TAB1 WHERE COL1 NOT IN(SELECT COL1 FROM TAB2)

          2. 使用NOT EXISTS的SQL語(yǔ)句:

          SELECT SUM(COL2) FROM TAB1 WHERE NOT EXISTS(SELECT * FROM TAB2 WHERE
          TAB1.COL1=TAB2.COL1)

          3. 使用外連接的SQL語(yǔ)句:

          SELECT SUM(A.COL2) FROM TAB1 A,TAB2 B WHERE A.COL1=B.COL1(+) AND B.COL1 IS NULL

          下面介紹IN、NOT IN、EXIST、NOT EXIST在DELETE和UPDATE語(yǔ)句中的效率提高方法。

          下面所舉的例子在Microsoft SQL Server 7.0下運(yùn)行通過(guò),但所推薦的方法在各種大型數(shù)據(jù)庫(kù)上皆適用。下面,我們將創(chuàng)建一些數(shù)據(jù)庫(kù)表和數(shù)據(jù),用于舉例說(shuō)明。我們將分別在表A(TA)中存入 10000條數(shù)據(jù),表B(TB)中存入5000條數(shù)據(jù)。

          SQL語(yǔ)句如下:

          CREATE TABLE TA
          (
          CA INT
          )
          CREATE TABLE TB
          (
          CA INT
          )
          CREATE TABLE TC
          (
          CA INT
          )
          CREATE TRIGGER TRA ON TC
          FOR INSERT
          AS
          DECLARE @MINT INT
          BEGIN
          SELECT @MINT=1
          WHILE (@MINT<=5000)
          BEGIN
          INSERT INTO TA VALUES(@MINT)
          INSERT INTO TB VALUES(@MINT)
          SELECT @MINT=@MINT+1
          END
          WHILE (@MINT<=10000)
          BEGIN
          INSERT INTO TA VALUES(@MINT)
          SELECT @MINT=@MINT+1
          END
          END
          GO
          INSERT INTO TC VALUES(1)
          GO

           刪除表A中表A和表B相同的數(shù)據(jù)

          1. 用IN的SQL語(yǔ)句:
          DELETE FROM TA WHERE TA.CA IN (SELECT CA FROM TB)

          2. 用EXISTS的SQL語(yǔ)句:
          DELETE FROM TA WHERE EXISTS (SELECT * FROM TB WHERE TB.CA=TA.CA)

          3. 使用連接的SQL語(yǔ)句:
          DELETE TA FROM TA,TB WHERE TA.CA=TB.CA

           刪除表A中表A存在但表B中不存在的數(shù)據(jù)

          1. 使用IN的SQL語(yǔ)句:
          DELETE FROM TA WHERE TA.CA NOT IN (SELECT CA FROM TB)

          2. 使用EXISTS的SQL語(yǔ)句:
          DELETE FROM TA WHERE NOT EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)

          3. 使用連接的SQL語(yǔ)句:
          DELETE TA FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA WHERE TB.CA IS NULL


           更新表A中表A和表B相同的數(shù)據(jù)
          1. 使用IN的SQL語(yǔ)句:
          UPDATE TA SET CA=CA+10000 WHERE CA IN (SELECT CA FROM TB)

          2. 使用EXISTS的SQL語(yǔ)句:
          UPDATE TA SET CA=CA+10000 WHERE EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)

          3. 使用連接的SQL語(yǔ)句:
          UPDATE TA SET TA.CA=TA.CA+10000 FROM TA,TB WHERE TA.CA=TB.CA


           更新表A中表A存在但表B中不存在的數(shù)據(jù)

          1. 使用IN的SQL語(yǔ)句:
          UPDATE TA SET CA=CA+10000 WHERE CA NOT IN (SELECT CA FROM TB)

          2. 使用EXISTS的SQL語(yǔ)句:
          UPDATE TA SET CA=CA+10000 WHERE NOT EXISTS (SELECT CA FROM TB WHERE TB.CA=TA.CA)

          3. 使用連接的SQL語(yǔ)句:
          UPDATE TA SET TA.CA=TA.CA+10000 FROM TA LEFT OUTER JOIN TB ON TA.CA=TB.CA WHERE TB.CA IS NULL

          posted on 2007-03-23 13:50 Bill111 閱讀(3621) 評(píng)論(2)  編輯  收藏

          評(píng)論

          # re: SQL執(zhí)行效率 2009-01-06 15:30 路人甲

          相當(dāng)糟糕~

          # re: SQL執(zhí)行效率 2011-06-09 15:00 nc

          nc

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 乌兰察布市| 临江市| 琼结县| 禹城市| 天气| 乌鲁木齐县| 宜兴市| 陆丰市| 赣州市| 潜山县| 铜山县| 玛纳斯县| 江口县| 云和县| 体育| 仁寿县| 池州市| 兴城市| 津市市| 车致| 阳朔县| 常山县| 边坝县| 梨树县| 遵义县| 南宫市| 麻城市| 三穗县| 沧州市| 太湖县| 三亚市| 岳池县| 新源县| 阿鲁科尔沁旗| 潜江市| 赣榆县| 锡林郭勒盟| 东阳市| 高雄县| 慈利县| 太原市|