多くのデータベース書き込み、約70%の挿入、30%の読み取りを含むアプリケーションに取り組んでいます。この比率には、1回の読み取りと1回の書き込みと見なす更新も含まれます。 insertステートメントを使用して、複数のクライアントが以下のinsertステートメントを介してデータベースにデータを挿入します。
$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");
問題は、insert_delayを使用するか、またはmysqli_multi_queryメカニズムを使用するかです。ステートメントはサーバーで最大100%のCPUを使用します。データベースでInnoDBエンジンを使用しているため、挿入の遅延は不可能です。サーバーへの挿入は〜36k/hrで、99.89%が読み取られます。また、selectステートメントを使用しています 単一のクエリでデータを7回取得 、このクエリの実行には150秒かかります。このタスクにはどのようなテクニックやメカニズムを使用できますか?サーバーのメモリは2 GBですが、メモリを拡張する必要がありますか?この問題を見てください、どんな提案も私に感謝します。
テーブルの構造:
+-----------------+--------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+-------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user | varchar(100) | NO | | NULL | |
| uniq_name | varchar(200) | NO | | NULL | |
| ad_name | varchar(200) | NO | | NULL | |
| ad_delay_time | int(11) | NO | | NULL | |
| track_time | timestamp | NO | MUL | CURRENT_TIMESTAMP | |
+-----------------+--------------+------+-----+-------------------+----------------+
私のデータベースには現在のステータスがあり、41kの挿入(書き込み)を示しています。これは私のデータベースでは非常に遅いです。
書き込みよりも読み取りが多いので、以下をお勧めします
InnoDBはINSERT DELAYED をサポートしていないため、大きなInnoDBバッファープールを使用することがINSERT DELAYEDに到達できる最も近いものです。すべてのDML(INSERT、UPDATE、およびDELETE)は、InnoDBバッファープールにキャッシュされます。書き込みのトランザクション情報は、すぐにREDOログ(ib_logfile0、ib_logfile1)に書き込まれます。バッファープールに送信された書き込みは、ibdata1(セカンダリインデックスのInsertBuffer、二重書き込みバッファー)を介してメモリからディスクに定期的にフラッシュされます。バッファープールが大きいほど、キャッシュできるINSERTの量が多くなります。 RAMが8GB以上のシステムでは、RAMとしてinnodb_buffer_pool_sizeとして75〜80%を使用します。RAMが非常に少ないシステムでは、25%(OSに対応するため)。
警告: innodb_doublewrite を0に設定すると、書き込みをさらに高速化できますが、データの整合性のリスクがあります。 innodb_flush_method をO_DIRECTに設定して、InnoDBをOSにキャッシュしないようにして、速度を上げることもできます。
デフォルトでは、REDOログの名前はib_logfile0およびib_logfile1で、それぞれ5MBになります。サイズはinnodb_buffer_pool_sizeの25%にする必要があります。 REDOログがすでに存在する場合は、my.cnfに新しい設定を追加し、mysqlをシャットダウンして削除し、mysql を再起動します。
ログバッファは、変更をREDOログにフラッシュする前にRAMで保持します。デフォルトは8Mです。ログバッファが大きいほど、ディスクI/Oは少なくなります。非常に大きなトランザクションには注意してください。これにより、COMMITがミリ秒単位で遅くなる場合があります。
MySQL 5.5およびMySQL 5.1 InnoDBプラグインには、InnoDBストレージエンジンが複数のCPUにアクセスするための設定があります。設定する必要があるオプションは次のとおりです。
MySQL 5.0を使用している場合は、MySQL 5.5にアップグレードします。 MySQL 5.1.37以前を使用している場合は、MySQL 5.5にアップグレードします。 MySQL 5.1.38以降を使用していて、MySQL 5.1のままにする場合は、InnoDBプラグインをインストールします。これにより、InnoDBのすべてのCPUを利用できます。
INT(2)は引き続き4バイトを使用します-おそらくあなたはTINYINT UNSIGNEDを意味していましたか?
Setnoにはいくつの異なる値がありますか?小さい場合、KEY(setno)は使用されません。 INSERTはそのインデックスを更新する必要があります。 KEYを削除すると、INSERTの速度が上がります。
CHAR(10)-flag
は常に10文字ですか?そしてutf8では?おそらくフラグVARCHAR(10)CHARACTER SET asciiを使用できます
挿入をバッチ処理します-一度に100は10倍の速度で実行されます。 (100を超えると、「収益の減少」に陥ります。)
自動コミットの価値は何ですか?各INSERTをBEGIN ... COMMITでラップしていますか? innodb_flush_log_at_trx_commitの値は何ですか?
キューを設定します。アプリケーションは、一度に1行ずつキューに書き込み、最後に挿入してから経過した時間の行数に基づいて、行を取り出してデータベースにバッチで挿入します。
一度に10,000個のインサートをバッチ処理するのが最も高速であるので、スイートスポットを見つけるためにテストする必要があります。
独自のシンプルなキューシステムを作成するか、既存のキューシステムを使用できます。次にいくつかの例を示します: HornetQ および File :: Queue 。ここに他のいくつかの良いオプションをリストするSEへの投稿があります: Perl、php、pythonのメッセージキュー 。