2016-09-17 3 views
2

hier ist meine Django ORM query:Wie kann ich diese wirklich langsame Abfrage optimieren, die von Django generiert wird?

Group.objects.filter(public = True)\ 
    .annotate(num_members = Count('members', distinct = True))\ 
    .annotate(num_images = Count('images', distinct = True))\ 
    .order_by(sort) 

Leider ist diese Groups sogar mit nur ein paar Dutzend mehr als 30 Sekunden dauern. Das Entfernen der annotate Aussagen macht die Abfrage deutlich bei schneller nur 3 ms ...

Meine Datenbank-Backend ist Postgres und hier ist die SQL und explain:

Executed SQL 
SELECT ••• FROM "astrobin_apps_groups_group" 
LEFT OUTER JOIN "astrobin_apps_groups_group_members" ON (
    "astrobin_apps_groups_group"."id" = "astrobin_apps_groups_group_members"."group_id" 
) 
LEFT OUTER JOIN "astrobin_apps_groups_group_images" ON (
"astrobin_apps_groups_group"."id" = "astrobin_apps_groups_group_images"."group_id") 
WHERE "astrobin_apps_groups_group"."public" = true 
GROUP BY 
    "astrobin_apps_groups_group"."id", 
    "astrobin_apps_groups_group"."date_created", 
    "astrobin_apps_groups_group"."date_updated", 
    "astrobin_apps_groups_group"."creator_id", 
    "astrobin_apps_groups_group"."owner_id", 
    "astrobin_apps_groups_group"."name", 
    "astrobin_apps_groups_group"."description", 
    "astrobin_apps_groups_group"."category", 
    "astrobin_apps_groups_group"."public", 
    "astrobin_apps_groups_group"."moderated", 
    "astrobin_apps_groups_group"."autosubmission", 
    "astrobin_apps_groups_group"."forum_id" 
ORDER BY "astrobin_apps_groups_group"."date_updated" ASC 

Time 
30455.9268951 ms 


QUERY PLAN 
GroupAggregate (cost=5910.49..8288.54 rows=216 width=242) (actual time=29255.329..30269.284 rows=27 loops=1) 
    -> Sort (cost=5910.49..6068.88 rows=63357 width=242) (actual time=29253.278..29788.601 rows=201888 loops=1) 
     Sort Key: astrobin_apps_groups_group.date_updated, astrobin_apps_groups_group.id, astrobin_apps_groups_group.date_created, astrobin_apps_groups_group.creator_id, astrobin_apps_groups_group.owner_id, astrobin_apps_groups_group.name, astrobin_apps_groups_group.description, astrobin_apps_groups_group.category, astrobin_apps_groups_group.public, astrobin_apps_groups_group.moderated, astrobin_apps_groups_group.autosubmission, astrobin_apps_groups_group.forum_id 
     Sort Method: external merge Disk: 70176kB 
     -> Hash Right Join (cost=15.69..857.39 rows=63357 width=242) (actual time=1.903..397.613 rows=201888 loops=1) 
       Hash Cond: (astrobin_apps_groups_group_images.group_id = astrobin_apps_groups_group.id) 
       -> Seq Scan on astrobin_apps_groups_group_images (cost=0.00..106.05 rows=6805 width=8) (actual time=0.024..12.510 rows=6837 loops=1) 
       -> Hash (cost=12.31..12.31 rows=270 width=238) (actual time=1.853..1.853 rows=323 loops=1) 
        Buckets: 1024 Batches: 1 Memory Usage: 85kB 
        -> Hash Right Join (cost=3.63..12.31 rows=270 width=238) (actual time=0.133..1.252 rows=323 loops=1) 
          Hash Cond: (astrobin_apps_groups_group_members.group_id = astrobin_apps_groups_group.id) 
          -> Seq Scan on astrobin_apps_groups_group_members (cost=0.00..4.90 rows=290 width=8) (actual time=0.004..0.348 rows=333 loops=1) 
          -> Hash (cost=3.29..3.29 rows=27 width=234) (actual time=0.103..0.103 rows=27 loops=1) 
           Buckets: 1024 Batches: 1 Memory Usage: 7kB 
           -> Seq Scan on astrobin_apps_groups_group (cost=0.00..3.29 rows=27 width=234) (actual time=0.004..0.049 rows=27 loops=1) 
             Filter: public 
Total runtime: 30300.606 ms 

Es wäre toll, wenn jemand einen Weg vorschlagen könnte dies optimieren. Ich fühle mich, als würde ich eine wirklich tief hängenden Frucht vermissen.

Danke!

+0

'... GROUP BY "astrobin_apps_groups_group". "Date_updated", "astrobin_apps_groups_group". "Id", "astrobin_apps_groups_group". "DATE_CREATED", "astrobin_apps_groups_group". "Creator_id". .. Dies wird ORDER BY und GROUP BY entsprechen. Und wahrscheinlich können Sie durch weniger keyfields gruppieren, sie scheinen alle funktional von 'id' (und/oder einem der Daten) abhängig zu sein – wildplasser

+0

Zunächst einmal sieht es so aus, als würden Sie 201K Zeilen bis zu 16 ... aggregieren Zeigen Sie uns auch einige der Aggregatfunktionen in Ihrer "Auswahl"? –

Antwort

0
  1. Was die Indizes, die auf astrobin_apps_groups_group sind und „astrobin_apps_groups_group_member, astrobin_apps_groups_group_image Tisch?
  2. Gibt es irgendwelche Aggregatfunktionen wie SUM, in Ihrer select verwendet COUNT? Wenn nein, dann können Sie alle Spalten aus GROUP BY
  3. entfernen
  4. der Plan zeigt die meiste Zeit zum Sortieren genommen wird. Wenn Sie einen Index für date_updated eingereicht mit NULLS LAST mit den neuesten Werten zuerst in Index zu erstellen, kann dann Planer diesen Index für die Sortierung verwenden.
  5. zum Sortieren wird Platte bekommen verwendet, was die teuerste Angelegenheit ist.Dies ist, weil Ihre Daten zum Sortieren gesammelt Nein ist t passt in den Speicher. Versuchen Sie, die WORK_MEM zu erhöhen - setzen Sie work_mem = '10MB'; SELECT .....
Verwandte Themen