2012-04-18 21 views
0

私たちは、基本的に私たちは、次のインデックスを持つページ大きなテーブルで挿入時間を改善するにはどうすればよいですか?

id int 
page_id int 
user_id int 
action_type enum(6) 
date_created datetime` 

上のユーザーアクションをログに記録MySQLのテーブルに次のデータ構造を持っている:

id Primary key 
user_id-page_id-date_created unique 
page_id-user_id-date_created 
user_id 
page_id-date_created 

私たちの問題は、このテーブルは、現在1.25億行を持っているということです1日に80万回の割合で成長しており、インサートの完了に約2時間かかります。 挿入は、3つの他のテーブルからデータを選択する3つのクエリによって行われます。この時間を改善するために何をすることができますか? mysqlを落として他のデータベースソリューションを試すべきでしょうか?

L.E:フィードバックに基づいて、私は詳細を提供しようとしています。 まず、テーブルはMyISAMです。これらの挿入はcronジョブで毎晩1回行われ、そのデータは削除されません。 ここでは、挿入をどのように扱うのですか。私はbig_tableとしてbigテーブルを参照し、構造が似ているので、3つのテーブルのそれぞれはcontent_tableになります。説明は約108.5百万の3つのテーブルの中で最大のものです。まず、私はphpを使用して挿入を開始する必要があるIDを取得します。

SELECT id FROM content_table WHERE date_created > "2012-04-18" ORDER BY id ASC LIMIT 1; 
+-----------+ 
| id  | 
+-----------+ 
| 107278872 | 
+-----------+ 
1 row in set (3 min 15.52 sec) 

EXPLAIN SELECT id FROM content_table WHERE date_created > "2012-04-18" ORDER BY id ASC LIMIT 1; 
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+ 
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+ 
| 1 | SIMPLE  | content_table | index | NULL   | PRIMARY | 4  | NULL | 1 | Using where | 
+----+-------------+------------------+-------+---------------+---------+---------+------+------+-------------+ 
1 row in set (0.06 sec) 

(私はそれを得るために非インデックス付きクエリの3分でOKです)そして、このIDを使用すると、私は

INSERT IGNORE INTO big_table (user_id, page_id, type, date_created) 
SELECT user_id, page_id, IF (is_admin,"admin_action","action") as type, created_time FROM content_table WHERE id >= "107278872"; 

を次のようにしますと、ここで選択したルックスのために説明する方法を説明します

EXPLAIN SELECT user_id, page_id, IF (is_admin,"admin_action","action") as type, created_time FROM content_table WHERE id >= "107278872"; 
+----+-------------+------------------+-------+---------------+---------+---------+------+--------+-------------+ 
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra  | 
+----+-------------+------------------+-------+---------------+---------+---------+------+--------+-------------+ 
| 1 | SIMPLE  | content_table | range | PRIMARY  | PRIMARY | 4  | NULL | 777864 | Using where | 
+----+-------------+------------------+-------+---------------+---------+---------+------+--------+-------------+ 
1 row in set (0.00 sec) 

ように私はまた、phpMyAdminの中でそれを試してみたし、周りの0.004sの時間はので、私はそれは時間ではなく、データのフェッチを取るの挿入だと思いました。サーバーについて知っているのは、クアッドコアxeon @ 2.4 ghzと16 GBのRAMですが、私はストレージについて何も知らない(私はその情報を持ってすぐに戻ってくるだろう)ということです。データはログには使用されません。ユーザーがページ、グループ化などで最もアクティブだったような統計を必要とするだけで、ユーザーはこれらの間隔を指定できます。

+0

あなたは何が時間がかかるか知っていますか?他のテーブルやインサート自体から選択していますか? –

+0

これは単にログとして機能する場合は、データベースではなく単純なファイルに置くことを考えなければなりません。しかし、どのようにデータを使用するかによって異なります。 – Sirko

+0

挿入前のインデックスを削除してから再構築してください。 –

答えて

3

あなたは可能性:

  1. それらが適切にインデックス化しているかどうかを確認するためにあなたは3つの他のテーブル上で実行するクエリでEXPLAIN PLANを。テーブルスキャンは削除する必要があります。
  2. クエリ内の各WHERE句の3つの他のテーブルにインデックスを追加します。
  3. データを日、週、月、またはその他の適切なメカニズムで分割して、最も古いデータをレポート/ウェアハウジングソリューションに移動することができます。
  4. トリガーソリューションが役立つかどうかを確認できます。
  5. データベースのプロファイルを作成し、ネットワークトラフィックを監視して、時間の所要時間を確認します。

すべてのリレーショナルデータベースは、あまりにも多くのデータを処理する必要があります。あなたの最初の考えはMySQLを落とすべきではありません。アーカイブ戦略が必要なものを把握しておく必要があります。特定の時間にトランザクションストアに必要なデータの量を正確に決定する必要があります。

+3

6.バッファ/ etcやチューニングのようなさまざまなdb/sessionおよびmemory設定を確認してください。 7. dbエンジンで利用可能なメモリを増やすことを検討してください。 –

+0

3テーブルのトリガを使用すると、大きなテーブルに挿入されたデータが高速に挿入されると思いますか? – Overdeath

+0

合計時間は同じかもしれませんが、差はより小さく、より頻繁に挿入されます。知覚される時間は少なく見えます。 – duffymo

0

  • エンジンタイプ
  • データが挿入されている方法
  • インデックス
  • など

あなたが挿入されているかを教えての第一として挿入に影響を与えるので、多くの要因があります。データ、ストレージエンジンがテーブル用に使用している2番目のものは、さらにクエリの挿入を最適化できます。一般的に、不要なインデックスとは、挿入速度が遅いということです。どのようにあなたがそれらを挿入する挿入read this article of dev.mysql for insert speed.

+0

ストレージエンジンはMyISAMです。私は、挿入がどのように行われたかについての詳細な情報で質問を更新しました。 – Overdeath

0

の速度により詳細な説明については

?この

//start loop 
insert into table values (1) 
//end loop 

はあなたにそれを試してみてください、あなたはこのような、あまりにも多くの値を挿入傾けることに注意してください(

//start loop 
//fill a variable 
//end loop 
insert into table values (1),(2),(3),(4) // where (1),(2),(3),(4) are values filled by the loop 

よりもはるかに遅くなりますようにのみ、第二のループquerysあたりのトランザクションの特定の番号を持つことができますデータ、私は通常200かそこらの値はかなり良いです)

インデックスが膨大であるため、問題を引き起こしているとは思わないので、phpmyadminはインデックスのサイズを表示します。サイズ - それはあなたに、そのstあまりにも多くのoring

関連する問題