2009-04-18 14 views
1

私はこれが私の質問をする適切な場所であることを願っています。mysqlクエリのサイズ制限ruby/mysql

私のmysqlのクエリは、現在、それはかなり長いクエリだと私はこれらすべてが私の問題を引き起こしている加入怖い私にはこの

@records = Record.find(:all, :select => "`records`.id, records.level as level, 
    (SELECT (count(b.id) + 1) 
    FROM records as a, records as b 
    WHERE a.id = records.id and b.skill > a.skill and b.created_at ='#{vandaag}') as ranktoday, 
    (SELECT (count(a1.id) + 1) 
    FROM records as a1, records as b1 
    WHERE a1.id = timestamp1.id and b1.skill > a1.skill and b1.created_at ='#{timestamp1}') as ranktimestamp1, 
    records.skill as skill, worlds.title as world, chars.name as name, vocs.voc as vocation, timestamp1.skill as timestamp1", 
    :conditions => ["`s1`.title = :skill AND `records`.created_at = :vandaag ", {:skill => params[:id], :vandaag => vandaag, :timestamp1 => timestamp1}], 
    :joins => " 
    LEFT OUTER JOIN `skilltypes` as `s1` ON `s1`.id = `records`.skilltype_id 
    LEFT OUTER JOIN `records` as `timestamp1` on `timestamp1`.character_id = `records`.character_id and `timestamp1`.created_at = '#{timestamp1}' 
    LEFT OUTER JOIN `characters` as `chars` ON `chars`.id = `records`.character_id 
    LEFT OUTER JOIN `vocations` as `vocs` ON `vocs`.id = `chars`.vocation_id 
    LEFT OUTER JOIN `worlds` ON `worlds`.id = `chars`.world_id", 
    :limit => "500", 
    :order => "`records`.skill DESC" 

のように見えます。
もし私が正しいとすれば、orderステートメントはmysqlにテーブルを持つすべてのレコードを結合させ、その結果の後にレコードを最初に注文するのではなく、最初の500個だけを制限してから参加させます。分かるでしょう?

と私は唯一の1000年の記録を持っていたが、現在私は380000件のレコードを持って、毎日、私は別の21000件のレコードを取得していた場合に問題が大きなことではないでしょう。

私の実際の質問は、異なるMySQLクエリで結合を分割する方が良いかどうかをどのように調べるのですか?
mysqlクエリがちょうど混乱して、あなたの笑い声に取り組んでいて、私を馬鹿みたいに見せてくれますか?

ローディング時間がひどいので、私はここでこだわっています。

Greetz、Rikkert

編集: そして私は があるべきだと思うcharacters.world_id、characters.vocation_id、records.character_id、records.skilltype_id、records.skill、records.world_id上のインデックスを持っています十分なGreetz、Rikkert

答えて

0

私の最初の質問は、インデックスを設定していますか?比較しているクエリのどの場所でも、関連する列にインデックスを設定する必要があります。

+0

私はcharacters.world_id、characters.vocation_id、records.character_id、recordsに索引を持っています。skilltype_id、records.skill、records.world_id 私は十分だと思います Greetz、Rikkert –

1

私は間違いなく、MySQLの専門家ではないんだけど、私の経験で私は副問い合わせを使用すると、いくつかのパフォーマンスのトラブルの原因となる可能性があることを発見しました。

私はそれらの使用を避けようとしますが、必ずしもそうすることはできません。

これはSOあなたが役立つかもしれないいくつかのより多くの情報を持っています

MySQL subselect performance question?

それはまた、私はトラブルを試してみて診断するには、これらの状況で使用EXPLAINコマンドについて語っています。

0

まず、実際にアクティブレコードを意図したとおりに使用していないようです。あなたのためにテーブル間の関連付けを管理しましょう。私は多くの手動SQLビルディングに頼らずに必要な情報を得る方法があると推測しています。あなたがあなたの例のために編集したものを選んでいるだけの場合は、お詫び申し上げます。

次に、EXPLAINを使用して、mysqlがどのようにクエリを実行しているかを理解してください。

MySQLの問い合わせプランナは非常に単純であり、多くの場合、Oracleに使用されている人、などのMySQLのオンラインドキュメントは、MySQLはインデックスを使用する方法についていくつかの良い情報を持って驚き。 、つまり必要な正確な情報の第二のテーブル(基本的にマテリアライズド・ビュー)を維持するために、オブザーバを使用:

複雑なクエリを最適化するための一般的なパターンは、正規化を解除することです。