2012-07-23 5 views
5

Sto cercando di accelerare alcune query utilizzando istruzioni preparate su un sito ad alto traffico. quello che non credo di capire correttamente è il vantaggio derivante dall'uso di affermazioni preparate a meno che non possano essere preparati su più connessioni. sembra che questo non sia possibile con PDO che non consente connessioni persistenti. ma le funzioni di connessione persistenti non consentono il PDO.mysql dichiarazioni preparate in modo permanente

consente di dire per amor di argomenti sto facendo funzionare una query 5.000 volte al secondo: SELECT * FROM some_table DOVE some_column LIKE 'some_value'

da quello che ho capito, DOP impedirebbe mysql da re-compilazione e la valutazione del query se dovessi cambiare "some_value" ogni volta che ho bisogno di interrogare. Capisco anche che "some_value" potrebbe essere trasmesso in binario anziché in ASCII per risparmiare larghezza di banda, ma non sarebbe un notevole risparmio se dovessi inviare l'intera query ogni volta che apro la connessione.

anche da quello che ho letto, le stored procedure non sono la soluzione, perché anche quelle non restano compilate attraverso connessioni multiple.

c'è qualche soluzione a questo problema? memorizzando una dichiarazione preparata sul server da qualche parte e facendola rimanere compilata in memoria e pronta a sparare non appena riceve le variabili?

esiste un modo per rendere questo possibile combinando il pool di connessioni con PDO? (anche se ho sentito che il connection pooling non è l'ideale perché può causare il blocco in determinate condizioni)

+0

Se si desidera utilizzare connessioni persistenti, è necessario impostare DOP :: ATTR_PERSISTENT nella gamma di opzioni del driver passata al costruttore DOP . Se si imposta questo attributo con PDO :: setAttribute() dopo l'istanza dell'oggetto, il driver non utilizzerà le connessioni permanenti. –

+1

Perché non usare Memcached? –

risposta

0

L'utilizzo di istruzioni preparate con MySQL non è in grado di rendere le query molto più veloci e impedisce anche il funzionamento della cache delle query. Hai bisogno di un po 'di cache di fronte al tuo database se hai davvero bisogno di eseguire la stessa query 5k/s. Memcached è popolare, così come Redis. A seconda di cosa stai facendo, anche gli elementi di memorizzazione nella cache o l'intera pagina potrebbero essere un'opzione.

+2

Questo non è vero, le dichiarazioni più preparate ** sono ** memorizzate nella cache! Vedi http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html –

+0

Ah, questo è un nuovo comportamento in 5.1.17, grazie. –

5

Dopo aver eseguito numerosi benchmark, abbiamo rilevato che le istruzioni preparate preparate sul server ci hanno fornito i maggiori vantaggi in termini di velocità. Ecco un esempio:

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

Ogni istruzione preparata nativa viene preparata sul server. Tuttavia, non li rende persistenti tra le connessioni. –

0

No, non v'è alcun modo per utilizzare le istruzioni preparate persistenti.

Tuttavia, v'è una soluzione ideale per la query in esecuzione 5.000 volte al secondo - Handlersocket