2012-07-23 124 views
1

是否可以優化以下查詢? webdte.docto a是具有數百萬個條目的非常大的表,並在所有查詢的列上運行索引。最後的排序順序非常重要。使用嵌套選擇優化查詢

SELECT 
    id_doc, 
    id_tip_doc, 
    id_est_doc, 
    folios.nro_fol, 
    seleccionable 
FROM 
(
    SELECT distinct(nro_fol) 
    FROM webdte.docto 
    WHERE 
     id_tip_doc IN 
     (
     SELECT distinct(id_tip_doc) 
     FROM webdte.docto 
     WHERE id_doc IN 
     (
      SELECT id_doc 
      FROM webdte.lib_doc 
      WHERE id_lib = 37 
     ) 
    ) AND 
     id_doc IN 
     (
     SELECT id_doc 
     FROM webdte.lib_doc 
     WHERE id_lib = 37 
    ) 
) AS folios JOIN webdte.docto AS docs ON docs.nro_fol = folios.nro_fol 
ORDER BY id_tip_doc, folios.nro_fol, id_est_doc; 

對不起,這裏是我的拳頭查詢方法的解釋。來自Egalitarian的答案已經很好,但也許它可以更快?謝謝!

Sort (cost=13745.13..13805.42 rows=24115 width=22)" 
    Sort Key: docs.id_tip_doc, docto.nro_fol, docs.id_est_doc" 
    -> Hash Join (cost=9240.19..11492.84 rows=24115 width=22)" 
     Hash Cond: (docto.nro_fol = docs.nro_fol)" 
     -> HashAggregate (cost=4424.81..4665.91 rows=24110 width=6)" 
       -> Hash Semi Join (cost=733.75..4364.54 rows=24110 width=6)" 
        Hash Cond: (docto.id_doc = lib_doc.id_doc)" 
        -> Seq Scan on docto (cost=0.00..2885.28 rows=105128 width=10)" 
        -> Hash (cost=432.38..432.38 rows=24110 width=4)" 
          -> Seq Scan on lib_doc (cost=0.00..432.38 rows=24110 width=4)" 
           Filter: (id_lib = 37)" 
     -> Hash (cost=2885.28..2885.28 rows=105128 width=22)" 
       -> Seq Scan on docto docs (cost=0.00..2885.28 rows=105128 width=22)" 
+1

您能向我們展示EXPLAIN和EXPLAIN ANALYZE的結果嗎?如果沒有這些信息,幾乎不可能優化查詢,因爲您無法看到實際問題出在哪裏。只有猜... – 2012-07-23 09:51:29

回答

0

我認爲在where子句來獲取獨特id_tip_doc是非常重要的意義還不如你反正選擇不同(nro_fol)。雖然優化此查詢的最佳方法之一是使用適當的索引,然後重新編寫查詢。

您可以創建以下指標(儘管它也取決於你的其他查詢): 1. webdte.lib_doc:id_lib 2. webdte.docto:id_doc + nro_fol

select id_doc,id_tip_doc,id_est_doc, folios.nro_fol ,seleccionable 

從(選擇不同(nro_fol) 從webdte.docto 其中在(選擇webdte.lib_doc其中id_lib = 37 id_doc) id_doc)對開
加入webdte.docto上docs.nro_fol = folios.nro_fol 順序文檔由id_tip_doc,對開。 nro_fol,id_est_文檔;

+0

非常感謝你。這是更快! – mugdiman 2012-07-24 02:26:32

1

我認爲你可以簡化爲:

SELECT id_doc 
     ,id_tip_doc 
     ,id_est_doc 
     ,nro_fol 
     ,seleccionable 
FROM webdte.docto d 
WHERE EXISTS (
    SELECT 1 
    FROM webdte.docto d0 
    JOIN webdte.lib_doc l USING (id_doc) 
    WHERE l.id_lib = 37 
    AND d0.nro_fol = d.nro_fol 
    ) 
ORDER BY id_tip_doc, nro_fol, id_est_doc; 

因爲EXISTS的,應該沒有必要

DISTINCT。如果在 nro_fol上有很多重複項,這可以加快查詢的速度。
您的原始查詢是相當多餘的。

+0

600毫秒!你是我的男人! – mugdiman 2012-07-24 02:32:21