【发布时间】:2013-11-25 14:38:37
【问题描述】:
我使用 XML 将部分 MySQL 数据库从一台服务器传输到另一台服务器。在这个 XML 中,我有我需要的所有数据库相关信息(数据和元数据)。一切正常,除了一件事——从information_schema获得外键约束。
问题在于性能。获取大约 100 个约束大约需要 7 分钟的 PHP 脚本加载!但是,如果一个人运行命令
SET GLOBAL innodb_stats_on_metadata = 0
这样的约束查询(即在 PHPMyAdmin 中)
SET GLOBAL innodb_stats_on_metadata = 0;
SELECT * FROM information_schema.KEY_COLUMN_USAGE
一切都需要大约 5 秒钟,然后就完成了。现在,这是一个巨大的节省时间,如果我能以下列方式使用它,那就太好了:
try{
$conn = $this->db->_pdo;
$conn->setAttribute(PDO::ATTR_AUTOCOMMIT, 0); //disable autocommit for transaction consistency
$conn->beginTransaction();
$this->db->_pdo->exec('SET GLOBAL innodb_stats_on_metadata = 0');
$query = $this->db->_pdo->prepare('
SELECT *
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_NAME = ?');
$query->bindParam(1, $table, PDO::PARAM_STR);
$query->execute();
$keys = $query->fetchAll(PDO::FETCH_ASSOC);
$conn->commit();
$conn->setAttribute(PDO::ATTR_AUTOCOMMIT, 1);
if(!empty($keys)) return $keys; else return false;
}catch (Exception $e){
$conn->rollback();
echo 'Caught exception: ', $e->getMessage(), "\n";
return false;
}
问题是exec命令在这里被忽略了,处理时间仍然很长。如果我将该命令放入准备中(在 SELECT 之前并用分号分隔),一切都会以错误结束。
所以我的问题是:如何在使用事务和准备语句的 PHP PDO 结构中设置 mysqli DB 参数 innodb_stats_on_metadata?
【问题讨论】:
-
语句被“忽略”的唯一原因是其中的错误
-
为什么要设置它GLOBAL?
-
我在这个 MySQL 命令领域并没有太多经验。 exec 完成得很好(我检查了它是否有错误,没有抛出)。但它仍然没有生效。至于你的第二个问题,能否请你给我一个提示,如何将它设置得比全局更好?
-
为会话设置它。表示没有“全球”一词
-
哇,它有效!我删除了 GLOBAL,现在执行时间不到 1 秒。我从没想过会这么简单:) ...非常感谢!
标签: php mysql pdo innodb prepare