2011-02-09 13 views
2

著者について概要私たちは、ベストブックを含むすべての著者を表示するクエリを探しています。このクエリの問題は、速度が不足していることです。約1500人の著者しか存在せず、クエリは現在概観を生成しており、現在は20秒かかる。サブクエリを高速化する方法

主な問題は、1人あたりのすべての書籍の平均評価を生成しているようです。我々はそれが結果セットを生成するために、完全な20秒を要した平均格付けで本を選択することにより、サブクエリが少し複雑にする場合は、次のクエリを選択することで は、それは、

select 
    person.id as pers_id, 
    person.firstname, 
    person.suffix, 
person.lastname, 
    thriller.title, 
    year(thriller.orig_pubdate) as year, 
    thriller.id as thrill_id, 
    count(user_rating.id) as nr, 
    AVG(user_rating.rating) as avgrating 
from 
    thriller 
inner join 
    thriller_form 
    on thriller_form.thriller_id = thriller.id 
inner join 
    thriller_person 
    on thriller_person.thriller_id = thriller.id 
    and thriller_person.person_type_id = 1 
inner join 
    person 
    on person.id = thriller_person.person_id 
left outer join 
    user_rating 
    on user_rating.thriller_id = thriller.id 
    and user_rating.rating_type_id = 1 
where thriller.id in 
    (select top 1 B.id from thriller as B 
    inner join thriller_person as C on B.id=C.thriller_id 
    and person.id=C.person_id) 
group by 
    person.firstname, 
    person.suffix, 
    person.lastname, 
    thriller.title, 
    year(thriller.orig_pubdate), 
    thriller.id, 
    person.id 
order by 
    person.lastname 

しかし、まだかなり速いです。次のように クエリは次のようになります。

select 
    person.id as pers_id, 
    person.firstname, 
    person.suffix, 
    person.lastname, 
    thriller.title, 
    year(thriller.orig_pubdate) as year, 
    thriller.id as thrill_id, 
    count(user_rating.id) as nr, 
    AVG(user_rating.rating) as avgrating 
from 
    thriller 
inner join 
    thriller_form 
    on thriller_form.thriller_id = thriller.id 
inner join 
    thriller_person 
    on thriller_person.thriller_id = thriller.id 
    and thriller_person.person_type_id = 1 
inner join 
    person 
    on person.id = thriller_person.person_id 
left outer join 
    user_rating 
    on user_rating.thriller_id = thriller.id 
    and user_rating.rating_type_id = 1 
where thriller.id in 
    (select top 1 B.id from thriller as B 
    inner join thriller_person as C on B.id=C.thriller_id 
    and person.id=C.person_id 
    inner join user_rating as D on B.id=D.thriller_id 
    group by B.id 
    order by AVG(D.rating)) 
group by 
    person.firstname, 
    person.suffix, 
    person.lastname, 
    thriller.title, 
    year(thriller.orig_pubdate), 
    thriller.id, 
    person.id 
    order by 
    person.lastname 

誰でもこのクエリをスピードアップするための良い提案を得ましたか。

+0

どのバージョンのSQL Serverですか? –

答えて

2

平均を計算するには、値を合計して(関連する)行の数で除算する必要があるため、テーブルスキャンが必要です。これは、あなたがたくさんの再スキャンをしていることを意味します。それは遅いです。一度平均を計算して保存できますか?これにより、事前に計算された値をクエリで使用できるようになります。 (はい、データを非正規化しますが、パフォーマンスの非正規化が必要な場合がありますが、パフォーマンスと最小限のデータとの間にはトレードオフがあります)。平均のストアとして一時テーブルを使用することが適切な場合があります。

+0

私たちはすでにそれについて話していましたが、誰かがこれを行う必要のない解決策を知りたいと思っていました。 –

+0

@Frederik:私は理解していますが、情報が必要な場合は必要です。緩和は本当に簡単なアプローチです。 –

関連する問題