0

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` );

これらの 2 行のクエリを約 120 実行する必要があります (つまり、全部で 240 のクエリ)。私のベンチマークによると、ビットの場合は 0.12 秒、CREATE TABLEビットの場合は 0.07 秒かかりALTER TABLEます。したがって、各クエリを個別に実行すると、完了するまでに約 24 秒かかります。

PDO で準備済みステートメントを使用して、240 個のクエリすべてを一度に実行する方法はありますか。つまりPDO::prepare、PHP を使用する方法はありますか。私は物事を大幅にスピードアップする方法を探しています。

前もって感謝します。

4

2 に答える 2

3

プリペアド ステートメントを使用すると、基本的にステートメントをストアド関数やプロシージャのように扱うことができます。

つまり、準備されたステートメントを定義して、異なるパラメーターで複数回呼び出します。

テーブル名、列名、またはキーワードをパラメーター化することはできません。値のみをパラメーター化できます (フィルター処理、並べ替え、挿入、更新など)。

したがって、準備されたステートメントは、パフォーマンスのために正確にしゃがむことができます。それどころか、2 つの操作を実行する必要がPREPAREあり、EXEC実際には処理が遅くなる可能性があります (ほんの少しだけ)。

データベース システムのトランザクションは、速度を向上させるために何もしません。それどころか、彼らはスピードを落とします。これは、すべてのデータが正しく存在するか、まったく存在しないか、halfway there状態がないことを保証するという、彼らが行うことに対して支払わなければならない代償です。何かが失敗した場合、何も試していないかのようにすべてをクリーンアップします。

また、MySQL のトランザクションは DDL (データ定義言語) に影響を与えません。つまりCREATEALTERステートメントはトランザクション モードで保持されず、すぐに実行されます。

すべての霧を一掃したので、次の質問に答えることができます。

  • すべてのクエリを 1 つの大きなクエリに連結します。
  • クエリごとに DB に繰り返し接続することは避けてください。各通信には時間がかかります。
  • $pdo->startTransaction();/をSQLコードで直接$pdo->commit();使用しないでください。START TRANSACTIONCOMMIT
  • すべてのクエリを一度に実行します。
  • 可能であれば、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);
于 2012-06-28T22:12:41.380 に答える
1

SQL クエリの連結を含む複数のアプローチを試した後でも、必要なパフォーマンスの向上は得られませんでした。

しかし、PDO から MySQLi に切り替えることで、「紙の上では」とはいえ、パフォーマンスが大幅に向上したことに気付きました。

PDO を使用する場合、SQL クエリは、制御をページに戻す前にスクリプト全体を実行する必要があります。ただし、MySQLi では、何らかの方法で SQL クエリを (バックグラウンドに) 渡し、制御をページに戻します。

したがって、120 個のテーブルを実行するのに 24 秒待つ代わりに、MySQLi を使用して 0.1 秒待ちます。理論的にはほぼ同じ時間がかかります (PHPMyAdmin または MySQL Workbench を使用する場合、すべてのテーブルが を使用して完全にリストされるまでに数秒かかることに気付くでしょうSHOW TABLES) が、私のスクリプトはページが戻る前に SQL クエリ全体を実行する必要があるため、ユーザー エクスペリエンスが向上します。

また、とにかくテーブルを使用する必要があるまでに 30 秒以上かかる可能性が高いため、大きな欠点は見られず、スクリプトははるかに高速に見えます。

したがって、インストール スクリプトを使用して多数のテーブルを作成する必要がある場合は、PDO を使用せず、代わりに MySQLi を使用することをお勧めします。一度に 1 つのテーブルを作成する場合、またはその他のデータベース タスクの場合は、引き続き PDO を使用する必要があります。

すべての貢献に感謝します。

于 2012-06-29T03:27:08.363 に答える