使用准备语句或其他方法优化PHP PDO中的表创建

时间:2012-06-28 17:51:17

标签: php mysql pdo

我正试图找到一种方法来加速PHP PDO中的MySQL表创建。我正在使用PHP 5.3和MySQL 5.

每个表都使用类似于以下代码的代码创建:

CREATE TABLE `moxedo`.`mox_config_8423` (`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT , `group_id` INT(3) UNSIGNED NOT NULL , `is_enabled` INT(1) UNSIGNED NOT NULL , `tag` VARCHAR(255) NOT NULL , `name` VARCHAR(80) NOT NULL , `value` VARCHAR(255) NOT NULL , `description` TEXT NOT NULL , `init_params` TEXT NOT NULL , `datetime_added` DATETIME NOT NULL , `datetime_lastmodified` DATETIME NOT NULL , `timestamp_univ` BIGINT(14) NOT NULL , PRIMARY KEY ( `id` ) )
ENGINE = InnoDB; 
ALTER TABLE `moxedo`.`mox_config_8423` ADD UNIQUE `ix_u_tag_ad` ( `tag` );

我有大约120个这样的双线查询要执行(总共有240个查询)。根据我的基准测试,CREATE TABLE位需要0.12秒,ALTER TABLE位需要0.07秒。因此,如果我单独运行每个查询,则需要大约24秒才能完成。

有没有办法可以在PDO中使用预准备语句一次执行所有240个查询,即使用PHP PDO::prepare。我只是在寻找一种显着提高速度的方法。

提前致谢。

2 个答案:

答案 0 :(得分:3)

预备语句允许您基本上处理类似存储函数或过程的语句。

这意味着你定义了准备好的语句,用不同的参数多次调用它。

它不允许您参数化表名或列名或关键字,只允许值(用于​​过滤,排序,插入,更新等)。

因此,准备好的声明可以准确地蹲下来表现。相反,你必须做两个操作PREPAREEXEC,这实际上可能会减慢速度(只是一点点)。

任何数据库系统中的事务都不会提高速度。相反,它们会降低速度。这是你必须支付的价格,这要确保所有数据都正确或根本没有,没有halfway there状态。如果出现问题,它会清理所有内容,就像它甚至没有尝试过任何东西一样。

MySQL中的事务对DDL(数据定义语言)没有影响,这意味着CREATEALTER语句不是在事务模式下保存,而是立即执行。

现在我们清除了所有的薄雾,我们可以回答这个问题:

  • 将所有查询连接成一个大查询;
  • 避免每次查询重复连接到数据库;每次沟通都需要时间;
  • 请勿在SQL代码中直接使用$pdo->startTransaction(); / $pdo->commit(); START TRANSACTION / COMMIT;
  • 一次运行所有查询;
  • 如果可能,请不要使用PHP生成查询;
  • 将其写入文件,或者使用PHP作为表前缀和其他小文本片段;
  • 不要指望通过检查ORM结构或类上的Reflection生成的SQL代码与大多数应用程序安装程序一样快,这些应用程序安装程序的文件包含安装所需的所有结构;

作为代码的示例,您可能会在打包部署应用程序之前运行(建议1,6):

$table_queries = '';
foreach($table_names AS $table_name) {
    $table_queries .= function_that_generates_table_query($table_name);
}
file_put_contents('all_table_creates_qeries.sql', $table_queries);

作为代码示例,您的部署者 / 用户可能会在应用程序自行安装时运行(建议2,4,5):

$table_queries = file_get_contents('all_table_creates_qeries.sql');
$pdo->exec($table_queries);

答案 1 :(得分:1)

在尝试多种方法(包括连接SQL查询)之后,我仍然无法获得我想要的性能提升。

然而,通过从PDO切换到MySQLi,我注意到我获得了显着的性能提升,尽管“纸上谈兵”。

当我使用PDO时,SQL查询必须在将控制权交还给页面之前执行整个脚本。但是,使用MySQLi它会以某种方式关闭SQL查询(到后台),然后将控制权发送回页面。

因此,我不是等待24秒执行120个表,而是使用MySQLi等待0.1秒。理论上需要大约相同的时间(因为如果你使用PHPMyAdmin或MySQL Workbench,你会注意到使用SHOW TABLES完成列出所有表之前需要几秒钟),但因为我的脚本没有在我的页面回来之前等待整个SQL查询执行,用户体验更好。

另外,在我需要使用表格之前可能需要超过30秒的时间,我没有看到任何重大缺点,而且你的脚本看起来要快得多。

因此,如果您需要使用安装脚本创建大量表,我建议不要使用PDO,而是使用MySQLi。如果您一次创建一个表,或者您正在执行其他数据库任务,则仍应使用PDO。

感谢所有的贡献。