Je suis un peu confus ici.
Voici ma requête (simplifiée): p> 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
3 Réponses :
Essayez d'inhéranger la requête
create index idx_registrations_did_date on registrations(document_id, date)
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;
Celui-ci prend 44 ans à exécuter: c
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. p>
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. P>
Ce sous-requête peut être le goulot d'étranglement ici et je ne peux pas comprendre le moyen de l'optimiser. P> blockQuote>
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.) P>
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. p>
xxx pré> Il sera efficacement supporté par: p>
xxx pré> 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. P> blockQuote>
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/...