2012-07-23 160 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