0
votes

L'ordre par le résultat de la sous-requête est ridiculement lent

Je suis un peu confus ici.

Voici ma requête (simplifiée): p> xxx pré>

et voici mon expliquer analyser code> Résultats: P>

Limit  (cost=46697025.51..46697025.56 rows=20 width=193) (actual time=80329.201..80329.206 rows=20 loops=1)
  ->  Sort  (cost=46697025.51..46724804.61 rows=11111641 width=193) (actual time=80329.199..80329.202 rows=20 loops=1)
        Sort Key: ((SubPlan 1))
        Sort Method: top-N heapsort  Memory: 29kB
        ->  Seq Scan on documents  (cost=0.00..46401348.74 rows=11111641 width=193) (actual time=0.061..73275.304 rows=11114254 loops=1)
              SubPlan 1
                ->  Aggregate  (cost=3.95..4.05 rows=1 width=4) (actual time=0.005..0.005 rows=1 loops=11114254)
                      ->  Index Scan using registrations_document_id_index on registrations  (cost=0.43..3.95 rows=2 width=4) (actual time=0.004..0.004 rows=1 loops=11114254)
                            Index Cond: (document_id = documents.id)
Planning Time: 0.334 ms
Execution Time: 80329.287 ms


1 commentaires

J'ai récemment répondu à une question similaire et il accélère beaucoup de questions similaires. Cela pourrait ne pas fonctionner comme bon ici, car je vois que Gordon a donné une solution avec la même idée à l'esprit mais l'a supprimé depuis. Stackoverflow.com/Questtions/58523659/...


3 Réponses :


0
votes

Essayez d'inhéranger la requête

create index idx_registrations_did_date 
  on registrations(document_id, date)


0 commentaires

1
votes

Ne pas utiliser une sous-requête scalaire:

SELECT documents.*,
       reg.register_date
FROM documents
JOIN (
  SELECT document_id, max(date) as register_date
  FROM registrations
  GROUP BY document_id
) reg on reg.document_id = documents.id;
ORDER BY register_date
LIMIT 20;


1 commentaires

Celui-ci prend 44 ans à exécuter: c



0
votes

Dans la requête complète réelle, j'ai aussi quelques filtres et cela prend jusqu'à 4 secondes pour exécuter, et c'est toujours trop lent.

Posez ensuite à propos de cette requête. Que pouvons-nous dire sur une requête que nous ne pouvons pas voir? Clairement, cette autre requête n'est pas exacte comme cette requête, à l'exception de la filtration des choses après tout le travail terminé, comme il ne pouvait pas être plus rapide (autre que celui de la chaleur de cache) que celui que vous avez montré. Cela fait quelque chose de différent, il doit optimiser différemment.

Ce sous-requête peut être le goulot d'étranglement ici et je ne peux pas comprendre le moyen de l'optimiser.

Le chronométrage du nœud de tri inclut l'heure si tout le travail qui l'a précédé, la durée du tri actuel est de 80329.206 - 73275.304 = 7 secondes, une minorité peut-être une minorité du temps total. . (Cette interprétation n'est pas très évidente de la sortie elle-même - elle de l'expérience.)

Pour la requête que vous avez montrée, vous pouvez l'obtenir assez rapidement, mais seulement probabiliste, en utilisant un Construction plutôt compliquée. xxx

Il sera efficacement supporté par: xxx

L'idée ici est que les 200 les plus récents Les inscriptions auront au moins 20 documents distincts parmi eux. Bien sûr, il n'ya aucun moyen de savoir certainement que cela sera vrai, vous devrez peut-être augmenter de 200 à 20000 (ce qui devrait toujours être assez rapide, comparé à ce que vous faites actuellement) ou même plus pour être sûr que vous obtenez le bonne réponse. Cela suppose également que chaque document distinct correspond exactement à un document.Id.


0 commentaires