Oui, je suis conscient que la normalisation des données devrait être ma priorité (telle quelle).
used_vehicle
, color
, doors
, mileage
, price
et ainsi de suite, au total 65.Vehicle
, VehicleInterior
, VehicleExterior
, VehicleTechnical
, VehicleExtra
(tous un à un) une avec la table principale Vehicle
).Supposons que j'aurai environ 5 millions de lignes (véhicules).
Sur SELECT
avec une clause WHERE
: les performances seront-elles améliorées (les deux cas indexés au moins sur IDs
):
Vehicle
table avec 65 colonnes ouVehicle
table avec JOINS
sur quatre autres tables (toutes avec 5 millions de lignes) pour renvoyer toutes les données relatives à Vehicle
?(Selon le moteur de base de données, pensez à PostgreSQL et/ou MySQL).
Vous appréciez vraiment les informations détaillées que vous pourriez avoir de votre expérience précédente?
En supposant que nous parlons de relations 1: 1 entre toutes les tables.
Dans l'ensemble le stockage est pratiquement toujours (sensiblement) moins cher avec une seule table au lieu de plusieurs tables dans une relation 1: 1. Chaque ligne a 28 octets de surcharge, plus généralement quelques octets supplémentaires pour un remplissage supplémentaire. Et vous devez stocker la colonne PK avec chaque table. Et avoir un index séparé (redondant) sur chacune de ces colonnes ... La taille est importante pour les performances.
Cela est même vrai si de nombreuses colonnes sont NULL dans la plupart des lignes car Le stockage NULL est très bon marché :
Lors de la récupération de toutes les colonnes, une seule table est sensiblement plus rapide que 5 tables réunies. C'est aussi beaucoup plus simple. Cinq tables peuvent être difficiles à joindre si toutes les lignes ne sont pas présentes dans toutes les tables. Avec les conditions WHERE
ciblant une seule table, il est assez facile d'ajouter d'autres tables avec LEFT JOIN
. Pas aussi banal si vous avez des prédicats sur plusieurs tables ...
Partitionnement vertical mai améliore encore les performances de certaines requêtes. Par exemple, si 90% de vos requêtes récupèrent les mêmes 5 colonnes sur les 65 disponibles, ce serait plus rapide avec une table contenant uniquement ces 5 colonnes.
OTOH, vous pourriez être en mesure de répondre à de telles requêtes sur quelques colonnes sélectionnées avec un index "couvrant" permettant analyses d'index uniquement .
Un autre candidat pour le partitionnement vertical: si vous avez beaucoup de mises à jour sur seulement quelques colonnes, alors que le reste ne change presque jamais. Dans un tel cas, il pourrait être considérablement moins coûteux de diviser des lignes, car Postgres écrit une nouvelle version de ligne pour chaque mise à jour. Il existe des exceptions pour les grandes valeurs stockées hors ligne ("TOASTed"). Plus de détails:
Cela dépend vraiment de la situation complète. En cas de doute, optez pour la solution simple d'avoir une seule table, surtout si elle représente bien la réalité: dans votre exemple, ce sont tous des attributs d'une voiture et ont du sens ensemble.
Une sélection sur une seule table devrait toujours être plus rapide. Dès que vous avez trouvé votre véhicule, vous avez déjà tous les détails.
Cependant, vous perdez l'efficacité de la normalisation. Par exemple, si 1 voiture avait de nombreux modèles avec différentes options.
Est-ce un db de référence de toutes les voitures? Ou une liste de véhicules d'occasion? Y aurait-il de nombreux exemples de la même marque/modèle avec les mêmes options?
Edit: je devrais qualifier ma réponse comme étant des rdbms génériques plutôt que spécifiques aux postgres. Je m'en remets à la réponse détaillée de @ Erwin spécifique aux postgres