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


Optimizing Table Creation in PHP PDO using Prepared Statements or Other

我正在尝试找到一种方法来加速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 个操作PREPAREEXEC实际上最终可能会减慢速度(只是一点点)。

任何数据库系统中的事务都不会对提高速度做任何事情。相反,它们会降低速度。这是您必须为他们所做的事情付出的代价,即确保所有数据都正确或根本没有,没有halfway there状态。如果某些东西失败了,它会清理所有内容,就好像它甚至没有尝试过任何东西一样。

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

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

  • 将所有查询连接成一个大查询;
  • 避免为每个查询重复连接到数据库;每次沟通都需要时间;
  • 不要在 SQL 代码中使用 $pdo->startTransaction();/$pdo->commit();直接使用 START TRANSACTION/COMMIT;
  • 一次性运行所有查询;
  • 如果可能,不要使用 PHP 生成查询;
  • 将其写入文件,也许使用 PHP 作为表前缀和其他小文本片段;
  • 不要指望通过检查ORM的结构或类反射生成的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);

在尝试了多种方法(包括连接SQL查询)之后,我仍然没有得到我想要的性能改进。

但是,通过从PDO切换到MySQLi,我注意到我获得了显着的性能改进,尽管是"纸上谈兵"。

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

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

此外,由于无论如何我可能需要 30 多秒才能使用这些表进行任何操作,我没有看到任何重大缺点,而且您的脚本似乎要快得多。

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

感谢所有的贡献。