web-dev-qa-db-fra.com

Beaucoup de colonnes vs peu de tables - en termes de performances

Oui, je suis conscient que la normalisation des données devrait être ma priorité (telle quelle).

  1. J'ai un tableau avec 65 colonnes stockant les données du véhicule avec des colonnes: used_vehicle, color, doors, mileage, price et ainsi de suite, au total 65.
  2. Maintenant, je peux diviser cela et avoir une table 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):

  1. Vehicle table avec 65 colonnes ou
  2. Vehicle 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?

12
Urim Kurtishi

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.

14
Erwin Brandstetter

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

0
Sir Swears-a-lot