11
votes

Performance de la base de données: filtrage sur la colonne vs table séparée

Je me demandais quelle est la meilleure approche pour la situation suivante:

J'ai une table de commande dans une base de données qui contient évidemment toutes les commandes. Mais celles-ci sont littéralement toutes les commandes, notamment les complexes / finis qui ne sont que communiqués comme «complet». À partir de toutes les commandes ouvertes, je veux calculer des trucs (comme une quantité ouverte, ouvrir des éléments, etc.). Quelle serait meilleure performance sage:

Table de commande 1 commandes avec toutes les commandes, y compris les commandes / archivées, et effectuez des calculs en filtrant le drapeau "complet"?

ou devrais-je créer une autre table, par ex. 'Ordres_archive', de sorte que la table des commandes ne contiendrait que des commandes ouvertes que j'utilise pour les calculs?

existe-t-il une différence de performance (claire) dans ces approches?

(b.t.w. Je suis sur un dB postgreSQL.)


0 commentaires

4 Réponses :


6
votes

ou devrais-je créer une autre table, par ex. 'Ordres_archive', de sorte que la table des commandes ne contiendrait que des commandes ouvertes que j'utilise pour les calculs?

Oui. Ils appellent cette entreposage de données. Les gens font cela car il accélère le système de transaction pour éliminer l'historique à peine utilisé. Premièrement, les tables sont physiquement plus petites et sont traitées plus rapidement. Deuxièmement, un rapport d'historique de longue date n'interfère pas avec le traitement transactionnel.

existe-t-il une différence de performance (claire) dans ces approches?

Oui. Prime. Vous pouvez restructurer votre historique de manière à ce qu'il ne soit plus dans 3NF (pour la mise à jour), mais dans un schéma d'étoiles (pour les rapports). Les avantages sont énormes.

Achetez le livre Toolkit Data Warehouse de Kimball pour en savoir plus sur la conception d'étoiles Schema et la migration de l'histoire des tables actives en tables d'entrepôt.


8 commentaires

Eh bien, il suffit d'archiver que d'anciens records sont encore loin d'un entrepôt de données. C'est un début si ...


Je suis d'accord avec cette réponse. Mais vous parlez massivement des quantités massives massives massives avant que vous n'ayez vraiment pas besoin de déployer quelque chose comme celui-ci. Une table de commande avec 100 000 commandes ne va probablement pas en avoir besoin


Je pensais que c'était appelé partitionnement de la table, vous utilisez une vue pour imiter la table complète.


@Sam Safran: Massive? Non. Vous trouverez de bons résultats en déplaçant seulement des milliers de rangées d'histoire à partir de tables actives dans les tables Star-Schema "Reporting". L'entrepôt de données ne signifie pas grand. Cela signifie optimisé pour les rapports. Qui est une architecture distinctive. Un "Data Mart" est ce que certaines personnes aiment les appeler afin que personne ne soit effrayée par des problèmes de dimensionnement.


@Sam Safran: Il existe une variété de techniques que vous pouvez utiliser. Vous pouvez séparer des tables en mettant en place des tables distinctes; Ensuite, vous pouvez les combiner dans une vue si vous voulez. Vous pouvez également laisser le SGBD gérer la partitionnement en interne; qui s'appelle partitionnement basé sur la valeur.


@Sam Safran: la partitionnement de la table n'est pas liée à la création d'un schéma d'étoiles approprié. Certaines personnes comme elle parce qu'il réduit la conflit de verrouillage et peut optimiser les requêtes avec un travail minimal. Cela n'améliore pas de manière spectaculaire la performance du rapport de la manière dont un schéma d'étoiles fait. Mais c'est peu coûteux.


@sleske: "Il suffit d'archiver les anciens disques" peut être à court terme. Ne commencez pas là. Commencez par l'histoire dans un schéma Star, ré-normalisé pour les rapports. Cela fait trois choses: archiver les anciens enregistrements et accélérer les performances transactionnelles et accélérer les rapports historiques.


Merci beaucoup pour cette réponse. Je vais regarder dans le livre de Kimball et le mettre en œuvre de cette façon. Je veux que ce soit «robuste» pendant une longue période, il peut donc s'agir de beaucoup de commandes à l'avenir. Créer des tables d'entrepôt Cela ressemble à la meilleure chose à faire.



7
votes

Ceci est un problème courant dans la conception de la base de données: la question de savoir s'il faut séparer ou "archiver" enregistrements qui ne sont plus «actifs».

Les approches les plus courantes sont:

  • Tout dans une table, marquez les ordres comme "complet", selon le cas. Avantages: solution la plus simple (à la fois de code et de structure-sage), une bonne flexibilité (par ex. Facile à "résoudre" commandes). Inconvénients: Les tables peuvent devenir assez volumineuses, un problème à la fois pour les requêtes et par ex. Sauvegardes.
  • Archivez de vieilles choses à séparer la table. Résout les problèmes de la première approche, au coût d'une plus grande complexité.
  • Tableau d'utilisation avec partitionnement basé sur la valeur. Cela signifie logiquement (à l'application) tout est dans une table, mais dans les coulisses, le SGBD met des objets dans des zones distinctes en fonction de la valeur de certaines colonnes. Vous utiliseriez probablement la colonne «complète» ou la «date d'achèvement de la commande» pour le partitionnement.

    Le dernier type d'approche combine les bonnes parties des deux premiers, mais nécessite une assistance dans le SGBD et est plus complexe à configurer.

    Remarque:

    tables qui stockent uniquement les données "archivées" sont communément appelées "tables d'archives". Certains SGBD fournissent même des moteurs de stockage spéciaux pour ces tableaux (par exemple MySQL), qui sont optimisés pour permettre une récupération rapide et une bonne efficacité de stockage, au coût des modifications / inserts lents.


0 commentaires

1
votes

Depuis que vous utilisez PostgreSQL, vous pouvez profiter de Index partiel . Supposons pour une commande inachevée que vous utilisez souvent orderdated , vous pouvez spécifier index comme celui-ci: xxx

Lorsque vous mettez cette condition, PostgreSQL n'exposera pas les commandes complétées, ce qui permet d'économiser HardDisk Espace et rendre l'indice beaucoup plus rapide car il ne contient que de petites données. Donc, vous obtenez la prestation sans les tracas de la séparation de table.

Lorsque vous séparez les données en commandes et commandes_Rarchive, vous devrez ajuster les rapports existants. Si vous avez beaucoup de rapports, cela peut être douloureux.

Voir la description complète de l'index partiel dans cette page: http://www.postgresql.org/docs/9.0/static/indexes-partial.html

EDIT: pour l'archivage, i Préfère créer une autre base de données avec un schéma identique, puis déplacez les anciennes données de la transaction DB sur cette archive DB.


0 commentaires

4
votes

jamais divisé ou séparer les données actuelles / archivées. C'est tout simplement incorrect. On peut appeler "entreposage de données" ou un godet de poisson, mais il est faux, inutile, et crée des problèmes qui n'étaient pas présents autrement. Le résultat est:

  • Tous ceux qui interrogent les données doivent maintenant le rechercher à deux endroits plutôt que d'un
  • et pire, faire l'ajout de valeurs agrégées manuellement (dans Excel ou autre)
  • Vous introduisez des anomalies dans la clé, l'intégrité est perdue (qui serait autrement unique par une seule contrainte de DB)
  • Lorsqu'une commande terminée (ou plusieurs) doit être modifiée, vous devez le pêcher hors de l'entrepôt et le remettre dans la "base de données"

    Si, et seulement si la réponse sur la table est lente, alors adressez-vous et améliorez la vitesse. Seul. Rien d'autre. Cela (dans tous les cas, j'ai vu) est une erreur d'indexation (un index manquant ou les colonnes incorrectes ou la séquence incorrecte des colonnes sont toutes des erreurs). Généralement, tout ce dont vous aurez besoin est la colonne IsComplete d'un index, ainsi que tout autre utilisateur à utiliser pour rechercher le plus souvent, dans / exclure les commandes ouvertes / complètes.

    Maintenant, si votre plate-forme SGMS ne peut pas gérer de grandes tables ou des ensembles de résultats importants, c'est un problème différent et que vous devez utiliser les méthodes disponibles dans l'outil. Mais en tant que problème de conception de base de données, il est tout simplement faux; Il n'est pas nécessaire de créer un duplicata, de le peupler et de le maintenir (avec tous les problèmes suivants), sauf si vous êtes limité par votre plate-forme.

    L'année dernière et cela, dans le cadre d'une affectation de performance ordinaire, j'ai consolidé de telles tables fractionnées avec des milliards de lignes (et devaient résoudre tous les problèmes de ligne en double qui auraient "n'existait pas", oui, 2 jours juste pour ça). Les tables consolidées avec les indices corrigés étaient plus rapides que les tables fractionnées; L'excuse que "des milliards de lignes a ralenti la table" était complètement fausse. Les utilisateurs m'aime parce qu'ils n'ont plus à utiliser deux outils et à interroger deux "bases de données" pour obtenir ce dont ils ont besoin.


4 commentaires

En réalité, ce n'est pas un entrepôt de données par définition. Une des nombreuses fausses définitions que les gens jettent. Un entrepôt de données est un ou contient des copies de rapport - il ne dit rien sur la suppression de l'original.


@À M. Tu as raison. Trop de jouets lâches et moelleux dans la salle informatique ces jours-ci.


Connexes: Stackoverflow.com/questions/179085/ ...


J'entends ce que vous dites. C'est une partition de base de données ne faisant pas partie de la conception.