【问题标题】:Is it possible to set innodb_stats_on_metadata in PHP PDO prepare statement?是否可以在 PHP PDO 准备语句中设置 innodb_stats_on_metadata ?
【发布时间】: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


【解决方案1】:

从语句中删除单词 GLOBAL。它肯定不会让没有 root 权限的用户设置 GLOBAL 状态变量。

【讨论】:

  • 好吧,我昨天有点太退出了,没有注意到我的日志中有错误:Caught exception: SQLSTATE[HY000]: General error: 1229 Variable 'innodb_stats_on_metadata' is a GLOBAL variable and should be set with SET GLOBAL ...您有什么建议吗?
  • 好吧。如果,如您所说,执行时间现在低于 1 秒 - 完全摆脱这一行。
  • Weeell,有趣的故事,它以错误结束并显示最后一个有效输出,从而极大地缩短了执行时间(duh)。另外,如果我们坚持使用 information_schema,我认为没有办法解决这个问题。显然,使用此元素的第 3 方操作非常耗时。我想我最好使用SHOW CREATE TABLE mytableregex 来获得约束。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2013-01-17
  • 2010-11-30
  • 2014-04-19
  • 1970-01-01
  • 2013-04-21
  • 1970-01-01
  • 2010-11-05
相关资源
最近更新 更多