ホームページ >バックエンド開発 >PHPチュートリアル >mysql テーブル列のレプリケーション、mysql 接続時間、メモリ制御。
一時テーブル temp_t とメイン テーブル table1 の 2 つのテーブルがあり、どちらも MyISAM で、それぞれに約 28W のレコードがあります。
Cron は、ネットワークから情報を 1 分ごとに取得するようにスケジュールし、最初にそれを temp_t に保存します (頻繁に書き込みます)。
次に cron は、情報を temp_t からメインテーブル table1 に 10 分ごとにコピーするようにスケジュールします (10 分ごとに頻繁に読み取り、書き込みします) 。
temp_t フィールド id (auto_increment)、title (varchar (200))、content (varchar (500))、date (DATETIME)、mykey (tinyint (1) デフォルト 1、これはコピーされたかどうかを判断するために使用されます。メインテーブル、コピー後 UPDATE は 2)
table1 フィールド ID (auto_increment なし)、title (varchar(200))、content (varchar(500))、date(DATETIME)
28W レコード、各データテーブルは各更新には約 2K ~ 3K のレコードが必要です。
直接コピーすると、MYSQL の接続時間が長すぎて、テーブル 1 がロックするような現象が発生し、テーブル 1 のクエリ時間が大幅に長くなります。最初に temp_t のデータからレコードを読み取り、それを json 配列として保存してから、データを table1 にコピーしたいと考えていますが、場合によっては、「メモリを割り当てられません」というエラーが発生し、サーバー全体がクラッシュします (これは json 配列です)。大きすぎて大量のメモリを占有します)。 PS: php.ini のメモリ制限が 64M に増加しました (しかし、根本的な原因ではなく症状を治療するものだといつも感じています。このようなコピー プロセスはそれほど多くのメモリを必要としません。重要なのは、コードが不合理であるということです) 。
require dirname(__FILE__) . '/../connection.php';mysql_select_db("news",$connextion);mysql_query("SET NAMES utf8");$query = mysql_query("SELECT * FROM temp_t where mykey = '1'");while($rows = mysql_fetch_array($query)){ mysql_query("UPDATE temp_t SET mykey='2' WHERE id='".mysql_real_escape_string($rows['id'])."'"); mysql_query("INSERT INTO table1 (id,title,content,date) values ('".mysql_real_escape_string($rows['id'])."','".mysql_real_escape_string($rows['title'])."','".mysql_real_escape_string($rows['content'])."','".mysql_real_escape_string($rows['date'])."'");}mysql_close($connextion);
ディスカッションに返信(解決策)
これら 2 つの文を順番に実行するだけです UPDATE temp_t SET mykey='2' WHERE mykey = '1'
わざわざphp転送する必要はありません
temp_tは一時的に保存されているので、転送されたデータを削除してみてはいかがでしょうか?
これら 2 つの文を順番に実行するだけです
INSERT INTO table1 (id,title,content,date) 値
SELECT id, title,content,date from temp_t where mykey = '1'
UPDATE temp_t SET mykey=' 2 ' WHERE mykey = '1'
わざわざphp転送する必要はありません
temp_tは一時的に保存されているので、転送したデータを削除してみてはいかがでしょうか?
temp_t のデータはまだ削除できません。挿入時にタイトルを繰り返さないという別の判断があります (繰り返し挿入を避けるため)
上司によると、このように実行するだけで十分ですか?まだテストしていないので、cron スクリプトを停止する必要があります。
私の経験に基づいて聞きたいのですが、このような 300 MB のデータ テーブルに一度に 2000 ~ 3000 のレコードを挿入すると、このスクリプトの実行にはどのくらいの時間がかかり、どのくらいのメモリを消費しますか? INSERT と SELECT の実行時間を高速化するには、特定の値のメモリを my.cnf に追加する必要がありますか?再度、感謝します。
require dirname(__FILE__) . '/../connection.php';mysql_select_db("news",$connextion);mysql_query("SET NAMES utf8");$query = mysql_query("SELECT * FROM temp_t where mykey = '1'");$jon = array();while($rows = mysql_fetch_array($query)){ $jon['a'] = $rows['id']; $jon['b'] = $rows['title']; $jon['c'] = $rows['content']; $jon['d'] = $rows['date']; $pjon .= json_encode($jon).',';}mysql_close($connextion);$njso = json_decode('['.substr($pjon,0,-1).']');foreach($njso as $nx){ if($nx->a){ require dirname(__FILE__) . '/../connection.php'; mysql_select_db("news",$connextion); mysql_query("SET NAMES utf8"); mysql_query("UPDATE temp_t SET mykey='2' WHERE id='".mysql_real_escape_string($nx->a)."'"); mysql_query("INSERT INTO table1 (id,title,content,date) values ('".mysql_real_escape_string($nx->a)."','".mysql_real_escape_string($nx->b)."','".mysql_real_escape_string($nx->c)."','".mysql_real_escape_string($nx->d)."'"); mysql_close($connextion); }}
3: 以前、その会社は 1 つのテーブルに 400 万個のデータが含まれており、一時テーブルから 1 つずつ読み取る方法が使用されていました。すべてをまとめて実行しますが、立ち往生するよりはマシです。
1: まず、一時テーブルが外部から読み取られていない場合は、memcache を使用しないのですか? そして、table1 が memcache を読み取ってそれを返します
メモリが足りないので、memcache がインストールされています。私は nginx サーバー クラスターです。この仮想空間には数十ドルの価値があります...
10G テーブルをコピーするには、my.cnf 内のいくつかの値のサイズを増やす必要がありますか?
300M ウォッチの動作が遅く、頻繁にフリーズするようにいつも感じています。人には天文学的な数字がありますが、頻繁に読み書きする人でもスムーズに仕事を進めることができます。
1: まず、一時テーブルが外部から読み込まれていない場合は、memcache を使用しないのですか? そして、table1 が memcache を読み取って返します。
メモリが足りないので、memcache をインストールします。私は nginx サーバー クラスターで、ここにいます ブロックは数十ドルの価値がある仮想空間です...
10G テーブル レプリケーションの場合、my.cnf 内のいくつかの値のサイズを増やす必要がありますか?
300M ウォッチの動作が遅く、頻繁にフリーズするようにいつも感じています。人には天文学的な数字がありますが、頻繁に読み書きする人でもスムーズに仕事を進めることができます。
その場合、データがどれほど大きくても複雑であっても、一度に 1 つの項目を使用する方が良いでしょう。 1~2秒に1通のメッセージ、1日経っても怖いです。
一度にこんなにたくさん注ぎ出す必要はない、一度に注ぎ出さなければ、大手グループ会社はそんなことはしないだろう。