2010-11-25 6 views
0

j'ai beaucoup de requêtes qui sont écrites comme:Comment optimiser requête imbriquée

 select thread_id as topic_id,title as topic    
    ,    
    isnull((select count(*) from tblmessages b where thread_id=a.thread_id and is_approved='Y' and sort_level>1    
    group by b.thread_id    
    ),0) as replies,    
    isnull((select count(*) from tblmessages b where thread_id=a.thread_id and isnull(new_post,'Y')='Y' and sort_level>1    
    group by b.thread_id    
    ),0) as NewPost,    
    isnull((select count(*) from tblmessages b where thread_id=a.thread_id and isnull(is_approved,'N')='N' and sort_level>1    
    group by b.thread_id    
    ),0) as NotClear,    

    sort_level,sort_index, from tblMessages a    
    where sort_level=1 and [email protected] 
    order by topic_id desc 

S'il vous plaît me dire comment optimiser et de mieux pour écrire de telles requêtes. parce que j'ai des tables avec des records 5,00,000. Il faut donc beaucoup de temps et parfois des temps morts.

Merci

+0

Est-ce cinq millions ou 50 millions d'enregistrements? –

+0

@Marcele: son 5,00,000 –

Répondre

1

Vous devez regrouper la sous-requête variuos dans un seul avec un nombre différent et utilisez une jointure pour mettre les données ensemble

la sous-requête doit être:

select thread_id 
    count(when isnull(is_approved,'N')='N' then 1 end) as replies, 
    count(when isnull(new_post,'Y')='Y' then 1 end) as NewPost, 
    count(when isnull(is_approved,'N')='N' then 1 end) as NotClear 
    from tblmessages 
    where sort_level>1 
    group by thread_id 

Alors que le finalquery est le suivant

select thread_id as topic_id,title as topic, 
    sort_level,sort_index , B.replies, B.NewPost, B.NotClear 
    from tblMessages a    
    join 
    (select thread_id 
    count(when isnull(is_approved,'N')='N' then 1 end) as replies, 
    count(when isnull(new_post,'Y')='Y' then 1 end) as NewPost, 
    count(when isnull(is_approved,'N')='N' then 1 end) as NotClear 
    from tblmessages 
    where sort_level>1 
    group by thread_id) as B 
    on a.thread_id = B.thread_id 
    where sort_level=1 and [email protected] 
    order by topic_id desc 
+0

@il_guru_ji: gr8 .. merci cela a amélioré ma performance de requête. –

0

Vous pouvez essayer de-normaliz ing un peu:

  1. Créer replies, NewPost et NotClear champs
  2. Ecrire une routine qui met à jour ces champs, il cron (période dépend de 3.)
  3. Rewrite plus/toutes les questions qui ont un impact ces champs les mettre à jour. Si vous réécrivez tous, exécutez 2. quelques fois par jour. Sinon, en fonction de l'intégrité des données dont vous avez besoin, quelques fois par heure.

Cela va clairement aider avec votre requête. Cependant, il a besoin de plus d'entretien que toute petite requête, presque jamais utilisé, peut briser la cohérence (penser à certains outils de modération pour BBs comme sujet divisé ...)

0
SELECT a.* 
FROM 
    (SELECT 
     thread_id AS topic_id, 
     title AS topic , 
     SUM(CASE WHEN is_approved='Y' AND sort_level > 1 THEN 1 ELSE 0 END) as replies, 
     SUM(CASE WHEN isnull(new_post,'Y')='Y' AND sort_level > 1 THEN 1 ELSE 0) END as NewPost, 
     SUM(CASE WHEN isnull(is_approved,'N')='N' AND sort_level > 1 THEN 1 ELSE 0 END) as NotClear, 
     sort_level , 
     sort_index, 
     category , 
     topic_id 
    FROM 
     tblMessages 
    ) a 
WHERE 
    a.sort_level=1 AND [email protected] 
ORDER BY 
     a.topic_id DESC 

Je n'ai pas pu tester, si certaines erreurs de syntaxe peuvent exister, mais vous obtenez la dérive?

+0

Vous aurez besoin d'un groupe par sur la requête imbriquée pour vos SUM – RLT