<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Decode360's Blog

    業精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 ::  :: 管理 ::
      397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
    用SQL計算100以內的質數
    ?
    ??? 蠻有意思的一段SQL,拿來看一下。
    ?

    ===========================================================
    作者: yangtingkun(
    http://yangtingkun.itpub.net )
    發表于: 2008.01.07 23:23
    分類: ORACLE
    出處:
    http://yangtingkun.itpub.net/post/468/450278
    -----------------------------------------------------------
    ?
    ??? 以前寫過一篇文章,描述如何使用PL/SQL來計算100以內的質數,今天重翻那篇文章的時候,突然想到,能不能用SQL來實現同樣的功能。
    ?
    ??? PLSQL計算質數: http://yangtingkun.itpub.net/post/468/53770
    ?
    ?
    ?
    ?
    ??? 其實這個功能用PLSQL實現最簡單,思路也很清晰,判斷一個數是否是質數,只需要檢查這個數能否被比它小的質數整除就可以了。但是這種操作通過SQL來實現就十分的困難,因此這里通過另外一種方式來實現這個功能——構造。
    ?
    通過查詢100以內的數,去掉所有的合數,剩下的就是質數了:
    ?
    SQL> WITH T
    ? 2 AS
    ? 3 (SELECT ROWNUM RN FROM DUAL CONNECT BY LEVEL < 100)
    ? 4 SELECT RN FROM T
    ? 5 WHERE RN > 1
    ? 6 MINUS
    ? 7 SELECT A.RN * B.RN FROM T A, T B
    ? 8 WHERE A.RN <= B.RN
    ? 9 AND A.RN > 1
    ?10 AND B.RN > 1;
    ?
    ??????? RN
    ----------
    ???????? 2
    ???????? 3
    ???????? 5
    ???????? 7
    ??????? 11
    ??????? 13
    ??????? 17
    ??????? 19
    ??????? 23
    ??????? 29
    ??????? 31
    ??????? 37
    ??????? 41
    ??????? 43
    ??????? 47
    ??????? 53
    ??????? 59
    ??????? 61
    ??????? 67
    ??????? 71
    ??????? 73
    ??????? 79
    ??????? 83
    ??????? 89
    ??????? 97
    ?
    25 rows selected.
    ?
    ?
    ?
    但是這種方法的效率明顯要比PL/SQL的效率要低,如果取10000以內的質數:
    ?
    ?
    SQL> SET TIMING ON
    SQL> SET AUTOT TRACE STAT
    SQL> WITH T
    ? 2 AS
    ? 3 (SELECT ROWNUM RN FROM DUAL CONNECT BY LEVEL < 10000)
    ? 4 SELECT RN FROM T
    ? 5 WHERE RN > 1
    ? 6MINUS
    ? 7 SELECT A.RN * B.RN FROM T A, T B
    ? 8 WHERE A.RN <= B.RN
    ? 9 AND A.RN > 1
    ?10AND B.RN > 1;
    ?
    1229 rows selected.
    ?
    Elapsed: 00:02:41.54
    ?
    Statistics
    ----------------------------------------------------------
    ??????? 511 recursive calls
    ???????? 81 db block gets
    ???? 180002 consistent gets
    ????? 65131 physical reads
    ??????? 648 redo size
    ????? 17139 bytes sent via SQL*Net to client
    ?????? 1276 bytes received via SQL*Net from client
    ???????? 83 SQL*Net roundtrips to/from client
    ????????? 2 sorts (memory)
    ????????? 1 sorts (disk)
    ?????? 1229 rows processed
    ?
    ?
    這個SQL執行了2分半種以上,當然這個SQL還可以進行一下優化,比如A的取值可以小于10000的開方,而B的取值可以小于10000除以最小的質數:
    ?
    ?
    SQL> WITH T
    ? 2 AS
    ? 3 (SELECT ROWNUM RN FROM DUAL CONNECT BY LEVEL < 10000)
    ? 4 SELECT RN FROM T
    ? 5 WHERE RN > 1
    ? 6 MINUS
    ? 7 SELECT A.RN * B.RN FROM T A, T B
    ? 8 WHERE A.RN <= B.RN
    ? 9AND A.RN > 1
    ?10 AND A.RN <= 100
    ?11 AND B.RN > 1
    ?12 AND B.RN <= 5000;
    ?
    1229 rows selected.
    ?
    Elapsed: 00:00:00.78
    ?
    Statistics
    ----------------------------------------------------------
    ????????? 2 recursive calls
    ???????? 23 db block gets
    ?????? 1820 consistent gets
    ???????? 16 physical reads
    ??????? 692 redo size
    ????? 17139 bytes sent via SQL*Net to client
    ?????? 1276 bytes received via SQL*Net from client
    ???????? 83 SQL*Net roundtrips to/from client
    ????????? 3 sorts (memory)
    ????????? 0 sorts (disk)
    ?????? 1229 rows processed
    ?
    ?
    優化后,SQL的執行效率提高了3個數量級,其實這個SQL仍然是可以優化的,考慮除了2以外,所有的質數均為奇數:
    ?
    ?
    SQL> WITH T
    ? 2 AS
    ? 3 (SELECT ROWNUM * 2 + 1 RN FROM DUAL CONNECT BY LEVEL < 4999)
    ? 4 SELECT 2 FROM DUAL
    ? 5 UNION ALL
    ? 6 (
    ? 7 SELECT RN FROM T
    ? 8 WHERE RN > 1
    ? 9 MINUS
    ?10 SELECT A.RN * B.RN FROM T A, T B
    ?11 WHERE A.RN <= B.RN
    ?12 AND A.RN > 1
    ?13 AND A.RN <= 100
    ?14 AND B.RN > 1
    ?15 AND B.RN <= 5000
    ?16 )
    ?17 ;
    ?
    1229 rows selected.
    ?
    Elapsed: 00:00:00.25
    ?
    Statistics
    ----------------------------------------------------------
    ????????? 2 recursive calls
    ???????? 15 db block gets
    ??????? 512 consistent gets
    ????????? 8 physical reads
    ??????? 648 redo size
    ????? 17138 bytes sent via SQL*Net to client
    ?????? 1276 bytes received via SQL*Net from client
    ???????? 83 SQL*Net roundtrips to/from client
    ????????? 3 sorts (memory)
    ????????? 0 sorts (disk)
    ?????? 1229 rows processed
    ?
    雖然通過SQL優化已經將極大的提高了效率,但是和PLSQL比,效率仍然相去甚遠:
    ?
    ?
    ?
    SQL> DECLARE
    ? 2 TYPE T_RECORD IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
    ? 3 V_RESULT T_RECORD;
    ? 4 I NUMBER DEFAULT 3;
    ? 5 N NUMBER DEFAULT 0;
    ? 6 BEGIN
    ? 7 --DBMS_OUTPUT.PUT_LINE(2);
    ? 8 V_RESULT(1) := 3;
    ? 9 WHILE(I < 10000) LOOP
    ?10 FOR J IN 1..V_RESULT.COUNT LOOP
    ?11 IF V_RESULT(J) * V_RESULT(J) > I THEN
    ?12 --DBMS_OUTPUT.PUT_LINE(I);
    ?13 V_RESULT(V_RESULT.COUNT + 1) := I;
    ?14 EXIT;
    ?15 END IF;
    ?16 IF TRUNC(I/V_RESULT(J)) = I/V_RESULT(J) THEN
    ?17 EXIT;
    ?18END IF;
    ?19 END LOOP;
    ?20 IF N = 2 THEN
    ?21 I := I + 4;
    ?22 N := 1;
    ?23 ELSE
    ?24 I := I + 2;
    ?25 N := N + 1;
    ?26 END IF;
    ?27 END LOOP;
    ?28 V_RESULT(0) := 2;
    ?29 END;
    ?30 /
    ?
    PL/SQL procedure successfully completed.
    ?
    Elapsed: 00:00:00.04
    ?
    這說明使用SQL并不一定就是最佳選擇,有的時候使用PLSQL效率反而會更高。使用合適的方法做適合的事情,一味追求使用單條SQL實現很可能會損失性能。
    ?

    ?
    posted on 2008-12-27 21:31 decode360 閱讀(348) 評論(0)  編輯  收藏 所屬分類: 05.SQL
    主站蜘蛛池模板: 国产又大又黑又粗免费视频| 国产亚洲精久久久久久无码77777 国产亚洲精品成人AA片新蒲金 | 亚洲精品亚洲人成在线观看下载| 久久免费国产精品| 91精品国产亚洲爽啪在线观看| www视频在线观看免费| MM1313亚洲精品无码久久| 亚洲精品无码成人AAA片| 无码国产精品一区二区免费 | 日韩精品人妻系列无码专区免费 | 日本最新免费不卡二区在线| 中文字幕乱码系列免费| 国产精品亚洲午夜一区二区三区| 亚洲精品无码日韩国产不卡?V| 久久综合给合久久国产免费| 亚洲成a∨人片在无码2023| 亚洲精品~无码抽插| 四虎影视大全免费入口| 全免费a级毛片免费看| 久久无码av亚洲精品色午夜| 亚洲人成电影在在线观看网色| 日本人的色道www免费一区| 免费日本一区二区| 香港特级三A毛片免费观看| 亚洲国产精品久久人人爱| 亚洲一级片免费看| 好吊妞998视频免费观看在线| 久久免费视频网站| 思思久久99热免费精品6| 456亚洲人成影院在线观| 亚洲gv猛男gv无码男同短文| 免费va人成视频网站全| AV大片在线无码永久免费| 成在人线av无码免费高潮水| 亚洲1区2区3区精华液| 亚洲w码欧洲s码免费| 亚洲成人在线网站| 亚洲午夜未满十八勿入网站2| 国产成人高清精品免费软件| 国国内清清草原免费视频99| 久草免费福利资源站|