Quel est le moyen le plus rapide de récupérer la dernière ligne d'une table?

11

J'ai une table PostgreSQL Prices, avec les colonnes:

  • price (Décimal)
  • product_id (Int)

Il y a aussi des colonnes created_atet updated_at.

Les prix sont mis à jour régulièrement et je garde les anciens prix dans le tableau. Pour un produit donné, le dernier prix du tableau est le prix actuel.

Quelle est la manière la plus efficace d'obtenir le dernier prix pour un produit spécifique:

  • Index product_idet requête pour le dernier enregistrement
  • Ajouter une troisième colonne active(booléenne) pour marquer le dernier prix et créer un indice composite ( product_idet active)
  • Ou autre chose?
Mike81
la source
4
L'utilisation d'un index partiel avec la condition where activeaiderait probablement encore plus à récupérer le dernier produit.
a_horse_with_no_name

Réponses:

11

Vous aurez besoin d'un index sur product_id quelle que soit la solution.

À condition d'avoir un index sur la colonne updated_at, et tout ce dont vous avez besoin est de récupérer "un produit spécifique" comme vous l'avez dit, alors je ferais:

select *
from Prices
where product_id = ?
order by updated_at desc 
limit 1

Mais si je n'obtenais pas les résultats que je voulais ou si j'avais besoin d'obtenir le prix actuel de nombreux produits, j'essaierais l'option d'ajouter une colonne active et de la définir sur N pour tous les prix autres que le nouveau lors de la fabrication. mises à jour des prix et ensuite je créerais un index partiel où actif comme suggéré par a_horse_with_no_name. Je n'irais là-bas que si j'en avais besoin car cela ajoute une couche de complexité de mise à jour des lignes de prix précédentes pour ne pas être actif, etc.

ETL
la source
1
Cette requête a besoin d'un index sur (product_id, updated_at)- ou sur (product_id, updated_at DESC)- pour être efficace. Pas seulement (updated_at).
ypercubeᵀᴹ
5

Sans connaissance du reste de votre base de données, vous pouvez vous permettre un peu de forme non normale pour accélérer la récupération des prix des produits (en supposant qu'il existe un prix pour chaque article).

Créez simplement une nouvelle colonne nommée last_pricede type pricedans votre producttable et créez un déclencheur AFTER INSERT ON EACH ROWsur votre pricetable. Chaque fois qu'un nouveau prix est créé, il met à jour le produit associé avec le dernier prix. De cette façon, chaque fois que vous récupérez un produit, vous récupérez également son dernier prix.

Depuis la version 9.3, PostgreSQL prend en charge les vues matérialisées. C'est une bonne façon de dénormaliser les données, en gardant une forme normale pour l'écriture et une vue dénormalisée pour la lecture. La mise à jour de la vue peut être déclenchée par le mécanisme LISTEN / NOTIFY de Postgres.

Greg
la source