sql >> Databasteknik >  >> RDS >> PostgreSQL

GROUP eller DISTINCT efter JOIN returnerar dubbletter

När du hämtar alla eller de flesta rader från en tabell, är det snabbaste sättet för den här typen av sökning vanligtvis att aggregera / disambiguera först och gå med senare :

SELECT *
FROM   products p
JOIN  (
   SELECT DISTINCT ON (product_id) *
   FROM   meta
   ORDER  BY product_id, id DESC
   ) m ON m.product_id = p.id;

Ju fler rader i meta per rad i products , desto större påverkan på prestandan.

Naturligtvis vill du lägga till en ORDER BY klausul i underfrågan definierar vilken rad för att välja formulär för varje uppsättning i underfrågan. @Craig och @Clodoaldo har redan berättat om det. Jag returnerar meta rad med det högsta id .

SQL Fiddle.

Detaljer för DISTINCT ON :

  • Välj första raden i varje GROUP BY-grupp?

Optimera prestanda

Ändå är detta inte alltid den snabbaste lösningen. Beroende på datadistribution finns det olika andra frågestilar. För det här enkla fallet som involverade en annan join, gick den här betydligt snabbare i ett test med stora tabeller:

SELECT p.*, sub.meta_id, m.product_id, m.price, m.flag
FROM  (
   SELECT product_id, max(id) AS meta_id
   FROM   meta
   GROUP  BY 1
   ) sub
JOIN meta     m ON m.id = sub.meta_id
JOIN products p ON p.id = sub.product_id;

Om du inte skulle använda det icke-beskrivande id som kolumnnamn skulle vi inte stöta på namnkollisioner och kunde helt enkelt skriva SELECT p.*, m.* . (Jag aldrig använd id som kolumnnamn.)

Om prestanda är ditt viktigaste krav, överväg fler alternativ:

  • en MATERIALIZED VIEW med föraggregerade data från meta , om dina uppgifter inte ändras (mycket).
  • en rekursiv CTE som emulerar en lös indexskanning för en stor meta tabell med många rader per produkt (relativt få distinkta product_id). ).
    Detta är det enda sättet jag vet att använda ett index för en DISTINCT-fråga över hela tabellen.


  1. Topp 5 MySQL-övervakningsverktyg

  2. Jämför Oracle RAC HA-lösning med Galera Cluster för MySQL eller MariaDB

  3. Vad betyder nyckelordet KEY?

  4. SQLite VAKUUM