2011-12-05 13 views
2

私は非常に単純なクエリを持っています。それが起きると、通常、クエリには約3〜6秒かかると言われています。クエリは次のとおりです。私は簡単なmysqlクエリの速度を向上させる方法

UPDATE company_users 
SET isonline=1, last_logon='2011-12-05 19:37:11', last_message=-1, 
    last_signal=-1, location=-1 
WHERE userid='3546600442XXXXX'; 

私は更新時に持っていた情報と同じように、ユーザーID比較を使用する必要があります。

データベース構造は以下の通りである:

company_users 0 PRIMARY 1つのID 197 \ N \ N BTREE
company_users 1 indx_userid 1ユーザID 197 \ N:

Field Type Null Key Default Extra 
id  int(11) NO PRI \N auto_increment 
userid varchar(20) NO MUL  
version varchar(3) YES  37 
owneruserid int(11) NO MUL 0 
simcard_phonenumber varchar(20) YES  \N 
registration_date date YES  \N 
labelname varchar(20) YES  \N 
isonline smallint(6) YES  0 
last_logon datetime YES  \N 
last_message int(11) YES  0 
last_voltage int(11) YES  0 
last_reboot datetime YES  \N  
connect_mode int(11) YES  1 
scheduleid int(11) YES MUL -1 
location  int(11) YES MUL -1 
img    varchar(50) YES   

Iは、以下のインデックスを持っています\ N BTREE
company_users 1 indx_location 1つの位置12 \ N \ N YES BTREE
company_users 1 indx_scheduleid 1 scheduleid 49 \ N \ N YES BTREE
company_us ers 1 indx_owneruserid 1 owneruserid A 197 \ N \ N BTREE

表には約300行あります。データベースは私のウェブサイトと同じサーバーにあります。これらのクエリは、PHPスクリプトを使用して実行されます。

うまくいけば、私は何が間違っているのか、どこで私の設定を調整できるのかを知るには十分な情報です。

UPDATE: Dennisの提案の後、私は遅いクエリログをもう一度見て、時間フレームに対して3つのステートメントが記録されていることに気付きました。

Query_time:5 Lock_time:0 Rows_sent:0 Rows_examined:0

Query_time:5 Lock_time:0 Rows_sentこれは、上記で特定した更新文の同じタイプだった二人のための情報でした。 0 Rows_examined:0

Query_time:4 Lock_time:0 Rows_sent:1 Rows_examined:1

この最後同じテーブル上に選択のためでした。私は(私はアップデートでそれを行う方法を知らなかったとして)、それが示したselect文に分析しました:

ID SELECT_TYPEのテーブル型possible_keysのキーkey_lenに参照行がEXTRA1 SIMPLE company_usersのconstが22 constの1

をindx_imei indx_imei
+2

300行のテーブルの場合、クエリはインデックスがなくても飛ぶ必要があります。しかし、 'user_id'のインデックスは、将来(あなたは既にそれを持っています)役に立つかもしれません。 – newtover

答えて

2

多くの索引を使用すると、select文の処理速度が向上しますが、挿入、更新および削除が遅くなります。私の最初の提案は、インデックスが削除され、時間が改善されているかどうかを確認するためにクエリを再実行することです。

+0

他のテーブルとこのテーブルで使用する結合に役立つインデックスがあります。これが間違っているのですか?この状況で使用するインデックスは、場所、スケジュールID、所有者IDのものです – dreza

+0

あなたが間違っていると、インデックスはテーブルを結合するときに速度を向上させるのに役立ちます。ただし、行の更新/挿入/削除を頻繁に行う予定がある場合は、索引の数を最小限に制限します。また、あなたの質問に説明計画を含めることができれば、それは多くの助けになると思います。あなたがEXPLAINに精通していない場合には、ここをクリックしてください。http://dev.mysql.com/doc/refman/5.5/en/using-explain.html –

2

300レコードのフラットテーブルでレコードを更新するという問題の問題は、インデックスには関係しないことをお勧めします。あなたの挿入ステートメントが別のステートメントによってブロックされているようです。特定の条件の下でのみ常に遅くなったり遅くなったりします。これにより、ブロックすることが可能性の高い候補に見えるようになります。本当にもっと情報が必要です。私は、可能性のあるものであるかどうかを調べるために、そのテーブルの可能なブロッキング・セレクトを調査し、トランザクション分離レベルや自動コミット・コンフィグレーションなどの前にこれらのクエリを最適化できるかどうか最初に確認します。

問題が選択クエリロックである場合、ロックせずに選択クエリを実行することによって、(場合によっては問題を解決して)検証することができます。これは、

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; 
SELECT * FROM TABLE_NAME ; -- Place your select query here 
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ; 

によって実行できます。ただし、このアプローチでは、いくつかの警告メッセージが表示されます。このアプローチを使用するのではなく、何が間違っているのかについてより多くの情報を得て、問合せを解決する方が良い方法です。

私はこのCoding Horror blogをいくつかの有用な洞察力があると覚えています。

+0

ありがとうございます。それはおそらくそのようなもののように見えます。しかし、それらは遅いクエリログにも表示されませんか?可能性のある犯人のように聞こえるので、ブロッキングの選択を特定するために私ができる技術やものはありますか – dreza

1

他の声明があなたのUPDATEステートメントをブロックしている可能性が最も高いAlexCに同意します。あなたの更新がブロックされていないことを確認したい場合は、2つのデータベースで作業できます。マスターデータベースではUPDATESとINSERTSを行い、2番目のデータベースは最初からレプリケートされ、すべてのSELECT処理が行われます。

また、実際にどの文が実際にあなたのクエリをブロックしているのかを確かめて、最適化を試みることができます。大量に選択されたデータベースでは、これは容易に達成できないかもしれません。

+0

ありがとうございました。 2つのデータベースが現時点で計画されているかどうかは不明ですが、将来的に調べる必要があるかもしれません – dreza

+0

実稼働環境の外観はわかりませんが、天気をテストして更新をブロックする可能性があります更新(ofc :)の実行中に他のクエリが実行されていないことを確認してください。データベースが稼働していない場合は、私は試してみて、更新クエリが実行されて天気がまだ遅いことを確認してください。 –

関連する問題