我有一个使用PHP的PDO库来访问mysql数据库的站点。 mysql数据库经过高度优化,具有所有合适的索引,可以快速查询查询等。我遇到了一些奇怪的行为,虽然与第一个运行特定Web服务的查询有关。
此特定Web服务针对数据库运行查询并返回json响应,然后将其反馈给jquery自动完成。
首次在客户端运行时的查询需要大约2秒才能运行,之后它会下降到百分之一秒,大概是由于innodb缓存。
如果我在新会话期间输入自动完成框中的条目,则第一个查询响应可能需要超过5秒,之后返回响应变得非常快。如果我然后离开网站一段时间,也许是一个小时(不是一个精确的措施,但为了争论,相对较长的一段时间)并回到它,再次观察到同样缓慢的第一个查询行为。
我正在使用持久连接,并且由于连接服务器上的连接数量有限。
我想知道你们中是否有人有任何想法可以让我更多地减轻初始延迟。
$DBH = null;
$host = "127.0.0.1";
$db_name = "my_db";
$user_name = "me";
$pass_word = "something";
try {
# MySQL with PDO_MYSQL
$DBH = new PDO("mysql:host=$host;dbname=$db_name;charset=utf8", $user_name, $pass_word, array(PDO::ATTR_PERSISTENT => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}
catch(PDOException $e) {
error_log( $e->getMessage(), 0 );
}
更新了回答
经过多次测试并且在彻底检查到它不是dns问题后,我正在检查innodb缓冲池路径。无论如何,我写了一个存储过程,它使用一个查询为数据库中的每个表生成一个查询,从而导致它们被缓存在innodb_buffer_pool中。为每个表生成sql查询的查询来自following SO question。我只对该查询进行了一次编辑,并放入了database()函数,以便它可以从调用它的任何数据库中工作。
我也进行了设置,以便可以通过PHP调用它,而无需等待脚本完成,因此您的正常应用程序将继续运行。
我希望这可以帮助别人。另外,为了提高效率,你可以将exec冷却到一个小函数中,只在特定时间运行它等等。
MySQL存储过程SQL
DELIMITER $$
USE `your_db_name`$$
DROP PROCEDURE IF EXISTS `innodb_buffer_pool_warm_up`$$
CREATE DEFINER=`user_name`@`localhost` PROCEDURE `innodb_buffer_pool_warm_up`()
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE sql_query VARCHAR(1000) DEFAULT NULL;
DECLARE sql_cursor CURSOR FOR
SELECT
CONCAT('SELECT `',MIN(c.COLUMN_NAME),'` FROM `',c.TABLE_NAME,'` WHERE `',MIN(c.COLUMN_NAME),'` IS NOT NULL')
FROM
information_schema.COLUMNS AS c
LEFT JOIN (
SELECT DISTINCT
TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME
FROM
information_schema.KEY_COLUMN_USAGE
) AS k
USING
(TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME)
WHERE
c.TABLE_SCHEMA = DATABASE()
AND k.COLUMN_NAME IS NULL
GROUP BY
c.TABLE_NAME;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN sql_cursor;
read_loop: LOOP
FETCH sql_cursor INTO sql_query;
IF done THEN
LEAVE read_loop;
END IF;
SET @stmt_sql = sql_query;
PREPARE stmt FROM @stmt_sql;
EXECUTE stmt;
END LOOP;
CLOSE sql_cursor;
END$$
DELIMITER ;
PHP调用存储过程
innodb_warm_up_proc_call.php
<?php
$DBH = null;
$host = "localhost";
$db_name = "your_db_name";
$user_name = "user_name";
$pass_word = "password";
try {
# MySQL with PDO_MYSQL
$DBH = new PDO("mysql:host=$host;dbname=$db_name;charset=utf8", $user_name, $pass_word, array(PDO::ATTR_PERSISTENT => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
$DBH->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
$sql = "CALL innodb_buffer_pool_warm_up()";
$STH = $DBH->prepare( $sql );
$STH->execute();
}catch( PDOException $e ) {
error_log( $e->getMessage() . ' in ' .$e->getFile(). ' on line ' .$e->getLine(), 0 );
}
?>
PHP以静默方式运行上述脚本而无需等待其完成
innodb_warm_up.php
<?php
$file_to_execute = dirname(__FILE__) . "/innodb_warm_up_proc_call.php";
//Run the stored procedure but don't wait around for a chat
exec("php -f {$file_to_execute} >/dev/null 2>&1 &");
?>
答案 0 :(得分:0)
在处理特定网络服务时,请将其域名更改为IP地址 最有可能的是它会消除这种延迟(由DNS查找引起)
答案 1 :(得分:0)
感谢您对此提供的所有帮助和建议。我彻底检查了dns和其他解决方案,但最后它结果是innodb页面缓冲池。我为自己编写了一个解决方案,并在上面的问题中完整地添加了它,所以希望它会有用。 再次感谢您的帮助。