2012-06-27

【程式】PostgreSQL : Prepared Statement - Zend Framework

Finder.png
一直以為 Prepared Statement 是DB 會自動去產生…
結果後來發現,原來不是……

詳細內容請見:PostgreSQL 9.0.8 Documentation - PREPARE

覺的比較重要的地方如下:
.....
Prepared statements only last for the duration of the current database session. When the session ends, the prepared statement is forgotten, so it must be recreated before being used again.
.....
Prepared statements have the largest performance advantage when a single session is being used to execute a large number of similar statements. The performance difference will be particularly significant if the statements are complex to plan or rewrite, for example, if the query involves a join of many tables or requires the application of several rules. If the statement is relatively simple to plan and rewrite but relatively expensive to execute, the performance advantage of prepared statements will be less noticeable.

就是居然 Prepared Statement 居然是要自己建,然後當Session 結束後,Prepared Statement 就會不見了…
所以他只適用在一次執行大量相似的 SQL,而且愈複雜的SQL,愈能看出他的好處。
這樣看起來,它就比較適合在每日的 Cron Job 中使用了。

這裡加上 Zend Framework 中使用 Prepared Statement 的用法
        $sql = 'SELECT * FROM MEMBER_INFO WHERE MEMBER_ID = ?';
        $stmt = new Zend_Db_Statement_Pgsql($db, $sql);
        $stmt->execute(array($memberId));
        $row = $stmt->fetch();
因為我是使用 PostgreSQL,所以會用 Zend_Db_Statement_Pgsql (非 ZF 原始檔案)
Zend_Db_Statement 是使用 Zend_Db_Statement_Mysqli

個人備忘: $db 可以使用 $this->getTable()->getAdapter() 來取得。

參考頁:
    PostgreSQL 9.0.8 Documentation - PREPARE
    Zend_Db_Statement



Update : 2012-07-10
後來發現, Zend Framework 的方式,是假的 Prepared Statement。
看 Db 的 Log ,都不是使用 Prepared Statement  的方式來執行。
所以要改成使用 PHP 原生 Prepared Statement 的 Function ,方式如下:
        $pStatName = 'UpdateViewedCnt';
        $dbConn = $this->getTable()->getAdapter()->getConnection();
        $sql = "
              UPDATE member_info
                 SET total_view_cnt = total_view_cnt + $1
               WHERE uid = $2
            ";
        // 第一次的話,要建 Prepared Statement 
        if (!Zend_Registry::isRegistered($pStatName)) {
            pg_prepare($dbConn, $pStatName, $sql);
            Zend_Registry::set($pStatName, true);
        }
        $resp = pg_execute($dbConn, $pStatName, array($num, $uid));
我先使用Zend Framework 去取得 Connection,這樣就不用再重建 Connection 了。
如果 Prepared Statement 己經存在,會有 Warning ,
所以我用 Zend_Registry 去記錄是否有建過。
這樣做了以後,我看 DB 的 Log ,現在己經有顯示是用 Prepared Statement 來執行了。







0 comments:

張貼留言