2011-08-31 70 views
1

我在使用外鍵在Postgres中排序時遇到了奇怪的問題(?)問題。這是第二個表&查詢,需要比無更長的時間。Postgres按國外主要性能排序?

EXPLAIN ANALYZE SELECT "spoleczniak_zdjecia"."id", "spoleczniak_zdjecia"."postac_id", "spoleczniak_zdjecia"."zdjecie", "spoleczniak_zdjecia"."opis", "spoleczniak_zdjecia"."data", "spoleczniak_zdjecia"."avatar", "spoleczniak_zdjecia"."tagi", "postac_postacie"."id", "postac_postacie"."user_id", "postac_postacie"."avatar", "postac_postacie"."ikonka", "postac_postacie"."imie", "postac_postacie"."nazwisko", "postac_postacie"."pseudonim", "postac_postacie"."plec", "postac_postacie"."wzrost", "postac_postacie"."waga", "postac_postacie"."ur_tydz", "postac_postacie"."ur_rok", "postac_postacie"."ur_miasto_id", "postac_postacie"."akt_miasto_id", "postac_postacie"."kasa", "postac_postacie"."punkty", "postac_postacie"."zmeczenie", "postac_postacie"."zdrowie", "postac_postacie"."kariera" FROM "spoleczniak_zdjecia" INNER JOIN "taggit_taggeditem" ON ("spoleczniak_zdjecia"."id" = "taggit_taggeditem"."object_id") INNER JOIN "taggit_tag" ON ("taggit_taggeditem"."tag_id" = "taggit_tag"."id") INNER JOIN "postac_postacie" ON ("spoleczniak_zdjecia"."postac_id" = "postac_postacie"."id") WHERE ("taggit_tag"."slug" = 'ja' AND "taggit_taggeditem"."content_type_id" = 922) ORDER BY "spoleczniak_zdjecia"."id" DESC LIMIT 28; 
                       QUERY PLAN 
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=27.88..27.89 rows=7 width=198) (actual time=2984.689..2984.697 rows=28 loops=1) 
    -> Sort (cost=27.88..27.89 rows=7 width=198) (actual time=2984.688..2984.692 rows=28 loops=1) 
     Sort Key: spoleczniak_zdjecia.id 
     Sort Method: top-N heapsort Memory: 32kB 
     -> Nested Loop (cost=2.31..27.78 rows=7 width=198) (actual time=1.063..2974.901 rows=9091 loops=1) 
       -> Nested Loop (cost=2.31..22.02 rows=7 width=109) (actual time=1.057..2899.010 rows=9091 loops=1) 
        -> Nested Loop (cost=2.31..19.92 rows=7 width=4) (actual time=1.046..2848.853 rows=9103 loops=1) 
          -> Index Scan using taggit_tag_slug on taggit_tag (cost=0.00..4.27 rows=1 width=4) (actual time=0.025..0.027 rows=1 loops=1) 
           Index Cond: ((slug)::text = 'ja'::text) 
          -> Bitmap Heap Scan on taggit_taggeditem (cost=2.31..15.56 rows=7 width=8) (actual time=1.019..2847.244 rows=9103 loops=1) 
           Recheck Cond: (tag_id = taggit_tag.id) 
           Filter: (content_type_id = 922) 
           -> Bitmap Index Scan on taggit_taggeditem_tag_id (cost=0.00..2.31 rows=7 width=0) (actual time=0.954..0.954 rows=9103 loops=1) 
             Index Cond: (tag_id = taggit_tag.id) 
        -> Index Scan using spoleczniak_zdjecia_pkey on spoleczniak_zdjecia (cost=0.00..0.29 rows=1 width=109) (actual time=0.005..0.005 rows=1 loops=9103) 
          Index Cond: (id = taggit_taggeditem.object_id) 
       -> Index Scan using postac_postacie_pkey on postac_postacie (cost=0.00..0.81 rows=1 width=89) (actual time=0.007..0.007 rows=1 loops=9091) 
        Index Cond: (id = spoleczniak_zdjecia.postac_id) 
Total runtime: 2984.760 ms 

這裏是無秩序的:

EXPLAIN ANALYZE SELECT "spoleczniak_zdjecia"."id", "spoleczniak_zdjecia"."postac_id", "spoleczniak_zdjecia"."zdjecie", "spoleczniak_zdjecia"."opis", "spoleczniak_zdjecia"."data", "spoleczniak_zdjecia"."avatar", "spoleczniak_zdjecia"."tagi", "postac_postacie"."id", "postac_postacie"."user_id", "postac_postacie"."avatar", "postac_postacie"."ikonka", "postac_postacie"."imie", "postac_postacie"."nazwisko", "postac_postacie"."pseudonim", "postac_postacie"."plec", "postac_postacie"."wzrost", "postac_postacie"."waga", "postac_postacie"."ur_tydz", "postac_postacie"."ur_rok", "postac_postacie"."ur_miasto_id", "postac_postacie"."akt_miasto_id", "postac_postacie"."kasa", "postac_postacie"."punkty", "postac_postacie"."zmeczenie", "postac_postacie"."zdrowie", "postac_postacie"."kariera" FROM "spoleczniak_zdjecia" INNER JOIN "taggit_taggeditem" ON ("spoleczniak_zdjecia"."id" = "taggit_taggeditem"."object_id") INNER JOIN "taggit_tag" ON ("taggit_taggeditem"."tag_id" = "taggit_tag"."id") INNER JOIN "postac_postacie" ON ("spoleczniak_zdjecia"."postac_id" = "postac_postacie"."id") WHERE ("taggit_tag"."slug" = 'ja' AND "taggit_taggeditem"."content_type_id" = 922) LIMIT 28; 
                      QUERY PLAN 
------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=2.31..27.78 rows=7 width=198) (actual time=1.113..1.482 rows=28 loops=1) 
    -> Nested Loop (cost=2.31..27.78 rows=7 width=198) (actual time=1.112..1.477 rows=28 loops=1) 
     -> Nested Loop (cost=2.31..22.02 rows=7 width=109) (actual time=1.102..1.292 rows=28 loops=1) 
       -> Nested Loop (cost=2.31..19.92 rows=7 width=4) (actual time=1.092..1.145 rows=28 loops=1) 
        -> Index Scan using taggit_tag_slug on taggit_tag (cost=0.00..4.27 rows=1 width=4) (actual time=0.017..0.017 rows=1 loops=1) 
          Index Cond: ((slug)::text = 'ja'::text) 
        -> Bitmap Heap Scan on taggit_taggeditem (cost=2.31..15.56 rows=7 width=8) (actual time=1.072..1.118 rows=28 loops=1) 
          Recheck Cond: (tag_id = taggit_tag.id) 
          Filter: (content_type_id = 922) 
          -> Bitmap Index Scan on taggit_taggeditem_tag_id (cost=0.00..2.31 rows=7 width=0) (actual time=0.989..0.989 rows=9103 loops=1) 
           Index Cond: (tag_id = taggit_tag.id) 
       -> Index Scan using spoleczniak_zdjecia_pkey on spoleczniak_zdjecia (cost=0.00..0.29 rows=1 width=109) (actual time=0.004..0.005 rows=1 loops=28) 
        Index Cond: (id = taggit_taggeditem.object_id) 
     -> Index Scan using postac_postacie_pkey on postac_postacie (cost=0.00..0.81 rows=1 width=89) (actual time=0.005..0.005 rows=1 loops=28) 
       Index Cond: (id = spoleczniak_zdjecia.postac_id) 
Total runtime: 1.562 ms 

什麼會導致問題?這是查詢?配置?我應該檢查任何特定的配置嗎?在我的最後一個問題中,有更復雜的查詢,但該查詢並不複雜。有什麼建議麼?

而順便說一句。那個查詢是由Django生成的(django-taggit是精確的)。 而順便說一句。第二部分,它不是硬件差在所有(i7處理器,16 GB的RAM,RAID 10 3x2的操作系統和數據+ 2個RAID1磁盤用於WAL,512MB RAID緩存+ BBU)的

純文本查詢:

選擇「spoleczniak_zdjecia」。「id」,「spoleczniak_zdjecia」。「postac_id」,「spoleczniak_zdjecia」。「zdjecie」,「spoleczniak_zdjecia」。「opis」,「spoleczniak_zdjecia」。「data」,「spoleczniak_zdjecia」。「avatar」, 「spoleczniak_zdjecia」。 「田儀」, 「postac_postacie」, 「ID」, 「postac_postacie」。 「USER_ID」, 「postac_postacie」, 「阿凡達」, 「postac_postacie」。 「ikonka」, 「postac_postacie」。 「IMIE」,「postac_postacie 「。」nazwisko「,」postac_postacie「,」pseudonim「,」postac_postacie「,」plec「,」postac_postacie「,」wzrost「,」postac_postacie「,」waga「,」postac_postacie「,」ur_tydz「,」postac_postacie「。 「ur_rok」,「postac_postacie」,「ur_miasto_id」,「postac _postacie」。 「akt_miasto_id」, 「postac_postacie」。 「開賽」, 「postac_postacie」。 「punkty」, 「postac_postacie」。 「zmeczenie」, 「postac_postacie」。 「zdrowie」, 「postac_postacie」。 「kariera」 FROM 「spoleczniak_zdjecia」 INNER JOIN 「taggit_taggeditem」 ON( 「spoleczniak_zdjecia」。 「ID」= 「taggit_taggeditem」。 「的object_id」)INNER JOIN 「taggit_tag」 ON( 「taggit_taggeditem」。 「TAG_ID」= 「taggit_tag」。 「ID」)INNER JOIN「postac_postacie 「ON(」 spoleczniak_zdjecia 「 」postac_id「= 」postac_postacie「。 」ID「),其中( 」taggit_tag「。 」金屬塊「= 'JA' AND 」taggit_taggeditem「。 」content_type_id「= 922)ORDER BY 」spoleczniak_zdjecia「。」 ID「DESC LIMIT 28;

+0

您能再次添加查詢的明文嗎?水平滾動不是我的專長;-) – wildplasser

+0

在這裏,你走了。:) – ThomK

+0

減少查詢是它的骨骼: 選擇 「身份證」 - PK - 「spoleczniak_zdjecia」 「Postac_id」 - FK FROM 「spoleczniak_zdjecia」 INNER JOIN 「taggit_taggeditem」 ON( 「spoleczniak_zdjecia。」 「spoleczniak_zdjecia。」 「ID」= 「taggit_taggeditem」 「的object_id」) - 。PK == PK INNER JOIN 「taggit_tag」 ON( 「TAG_ID」= 「taggit_tag」 「ID」) 「taggit_taggeditem。」 - FK - > PK INNER JOIN 「postac_postacie」 ON( 「postac_id」= 「postac_postacie」 「ID」 「spoleczniak_zdjecia。」。) - FK - > WHERE PK 「taggit_tag '' 蛞蝓 '=' I「 AND」 taggit_taggeditem。 「」 content_type_id 「= 922 ORDER BY」 spoleczniak_zdjecia。 「」 ID「DESCLIMIT 28; – wildplasser

回答

1

的區別就在這裏的EXPLAIN輸出的第二行:

-> Sort (cost=27.88..27.89 rows=7 width=198) (actual time=2984.688..2984.692 rows=28 loops=1) 

注意「實際時間」是相當多的查詢的全部時間。排序不僅需要一堆比較(即排序任何成本),還需要額外的數據管理,服務器需要將一些數據(行或指向行的指針)複製到臨時位置,以便在不影響其他任何內容的情況下對其進行排序。

任何查詢將需要更長的時間與排序,除非你很幸運,你的排序順序相匹配的磁盤和優化可以看到,它們匹配起來。

0

第二個返回您找到的前28個記錄,無論順序。

首先你必須定購結果然後返回28條第一條記錄。

如果數據沒有被修改,與ORDER BY意志查詢返回相同的共有28條記錄每一次。

但是第二個查詢可以每次執行時都會返回28個不同的記錄。結果不能保證。