2012-07-23 125 views
5

我期待在高流量網站上使用預準備語句加速一些查詢。我不認爲自己正確理解的是使用準備好的語句的好處,除非他們可以通過多個連接保持準備。看起來這對PDO來說也是不可能的,這也不允許持久連接。但持久連接功能不允許PDO。mysql永久準備語句

可以說,爲了討論我運行一個查詢5000次每秒: SELECT * FROM some_table WHERE some_column LIKE「SOME_VALUE」

從我個人理解,PDO將阻止MySQL的從重新編譯和評估每次我需要查詢時,查詢是否要更改「some_value」。我也明白,「some_value」可以用二進制而不是ASCII來傳輸以節省帶寬,但如果我每次打開連接時都必須發送整個查詢,那麼節省的不多。

也從我讀過的,存儲過程不是解決方案,因爲那些不保留編譯通過多個連接。

有沒有解決這個問題的辦法?將準備好的語句存儲在服務器的某個地方,讓它在內存中編譯並準備在收到變量後立即觸發?

有什麼辦法可以通過將連接池與PDO結合來實現嗎? (雖然我也聽到了連接池是不理想的,因爲它可能會導致在一定的條件下阻止)

+0

如果你想使用持久連接,則必須設置PDO :: ATTR_PERSISTENT的驅動程序選項傳遞給PDO構造數組中。如果在實例化對象後將此屬性設置爲PDO :: setAttribute(),則驅動程序將不會使用持久連接。 – 2012-07-23 02:39:58

+1

爲什麼不使用Memcached? – 2012-07-23 02:41:28

回答

0

使用準備好的語句與MySQL是不太可能使你的查詢速度更快,並阻止查詢緩存從工作壓力太大。如果您確實需要運行相同的查詢5k/s,則需要在數據庫前面進行緩存。 Memcached和Redis一樣受歡迎。根據你在做什麼,緩存元素或整個頁面也可能是一個選項。

+2

這不是事實,大多數準備好的語句**都被緩存了!見http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html – 2012-07-23 05:33:18

+0

啊,這是新的行爲在5.1.17,謝謝。 – 2012-07-23 13:03:43

5

在運行衆多基準測試之後,我們發現在服務器上準備的報表爲我們提供了最大的速度優勢。這裏有一個例子:

DROP PROCEDURE IF EXISTS get_user; 

DELIMITER // 

CREATE PROCEDURE get_user(IN v_user VARCHAR(255)) 
DETERMINISTIC 
READS SQL DATA 
SQL SECURITY INVOKER 
COMMENT '' 
proc: BEGIN 
    SET @user = v_user; 

    IF ISNULL(@get_user_prepared) THEN 
     SET @get_user_prepared = TRUE; 

     SET @sql = "SELECT * FROM mysql.user WHERE user = ?"; 

     PREPARE get_user_stmt FROM @sql; 
    END IF; 

    EXECUTE get_user_stmt USING @user; 
END; 
// 

DELIMITER ; 
+0

準備在服務器上準備的每個準備好的語句。這不,但是,使它們之間的連接持續。 – 2013-05-21 19:09:53

0

不行,沒有辦法使用持久預處理語句。

然而,有一個每秒運行5000次查詢的理想解決方案 - Handlersocket