2009-07-07 12 views
0

私はこの1つで私を助けることを願っています。私はtwitterサービス(http://foller.me)をパブリックベータ2に更新しようとしていますが、私は少なくとも2〜3秒でページを出すことができるまでこれをしたくありません。現在のバージョンは十分にシンプルですが、私が開発している開発版はかなり複雑です。MySQLの最適化と微調整のヒントを探してください

これは、私のリレーションとプロファイルの両方のテーブルに約200万行含まれています。プロファイルテーブルには一般的なツイッターユーザー情報が含まれており、リレーションテーブルには[twitter_idfollowed_by]のエントリが含まれています。これらのエントリはどちらもUNIQUEインデックスにあります。しばらくの間毎回実行されるcronジョブがあり、Twitter APIにユーザーのフォロワーについて問い合わせて、リレーションシップデータベースにデータを挿入します。

私はInnoDBを使用しているため、テーブルはロックされていませんが頻繁に更新されるため、特にcronジョブが実行されているときにクエリキャッシュに十分なヒットが得られません。

私はSELECT screen_name FROM profiles WHERE twitter_id IN (SELECT followed_by FROM relations WHERE twitter_id = 'kovshenin')のようなステートメントを持っています。私はそれを行うには非常に良い方法ではないと確信しています。これらは、私がそれをオンにするとmysql-slowログに出てくるものです(他にもたくさんあります)。

とにかく、私は自分のプロジェクトで良いランタイムを達成するための一般的なヒントが必要です。

ありがとうございます。

+0

TagCloudを成長させる際に私たちが発見したいくつかの問題と解決策をお知らせいたします。 2005年に私に直接連絡したいと思っています。連絡先については、http://blog.gahooa.com/aboutを参照してください。 – gahooa

+0

こんにちはジェイソン、私はあなたに電子メールを落としました。ありがとう – kovshenin

答えて

3

次のようにクエリを書き換えしよう:

SELECT screen_name 
FROM profiles p 
WHERE EXISTS 
     (
     SELECT 1 
     FROM relations r 
     WHERE r.twitter_id = 'kovshenin' 
       AND r.followed_by = p.twitter_id 
     ) 

をまた、あなたがUNIQUEインデックスを持っているので、あなたはおそらくJOINとしてクエリを書き直すの恩恵を受ける、:

SELECT p.screen_name 
FROM relations r 
JOIN profiles p 
ON  p.twitter_id = r.followed_by 
WHERE r.twitter_id = 'kovshenin' 

にあなたはあり頻繁に使用される列でいくつかのインデックスを作成することで、オーバーヘッドが余分にかかり、恩恵を蒙ります。例えば

、このクエリ:あなたはprofiles (twitter_id, screen_name)に複合インデックスを作成した場合

SELECT p.screen_name 
FROM relations r 
JOIN profiles p 
ON  p.twitter_id = r.followed_by 
WHERE r.twitter_id = 'kovshenin' 

も、profilesに見えません。

screen_name選択した場合は(とのみscreen_nameを、私は。すなわち、それは常にSELECT、リスト内の列のみです)、アプリケーションのための十分な一般的なクエリは、あなたがこのようなインデックスを作成することを検討すべきです。また

1

EXPLAIN SELECT * FROM PROFILES 

これはあなたのクエリを遅くしているもの(ないインデックスは、無参加していないなど)が表示されますコマンドラインにEXPLAIN使用してスロークエリログにクエリをチェックして、低速のデバッグを支援するようにしてくださいもの。 this answerでMySQLプロファイラの情報をチェックして、テーブルロック、クエリキャッシュのチェック/書き込みなどの深いタイミングを得ることができます。