D'une part, c'est bien que vous ayez ouvert une nouvelle question. Mais d'un autre côté, en extrayant une requête et en demandant si elle s'exécute plus rapidement, perd le contexte de la question précédente, la nouvelle question est trop isolée. Comme vous le savez certainement, l'administration d'une base de données, la gestion des ressources (mémoire/cache, disque, cycles CPU), la gestion du code (bon ou mauvais) qui utilise ces ressources font partie de l'image globale. La performance est un jeu de trading, rien n'est gratuit.
-
Le principal problème que j'ai eu était la duplication de la colonne EndDate, qui est facilement dérivée. Les colonnes dupliquées équivaut à Mettre à jour les anomalies. Smirkingman a fourni l'exemple classique :certaines requêtes obtiendront un résultat et d'autres requêtes obtiendront l'autre. Ce n'est tout simplement pas acceptable pour les grandes organisations ; ou dans des banques (du moins dans les pays développés) où les données sont auditées et protégées. Vous avez enfreint une règle de normalisation de base et des pénalités doivent être payées.
-
Mettre à jour les Anomalies ; deux versions (déjà détaillées). Les auditeurs peuvent ne pas réussir le système.
-
Taille de la table
Dans toute grande table, c'est un problème, et en particulier dans les séries chronologiques ou les données temporelles, où le nombre de colonnes est petit et le nombre de lignes est énorme. Alors quoi, diront certains, l'espace disque est bon marché. Oui, les MST aussi. Ce qui compte, c'est à quoi il sert et à quel point on en prend soin.-
L'espace disque
Peut être bon marché sur un PC, mais pas sur un serveur de production. Fondamentalement, vous avez ajouté 62 % à la taille de la ligne (13 plus 8 égale 21) et donc à la taille du tableau. À la banque qui m'est actuellement affectée, chaque service propriétaire des données est facturé comme suit, le stockage basé sur SAN est tout ce qu'il y a. Les chiffres sont par Go par mois (il ne s'agit pas d'une banque australienne haut de gamme) :1,05 $ pour RAID5 Unmirrored
(nous savons que c'est lent, mais c'est bon marché, mais ne mettez pas d'informations importantes dessus, car s'il se casse, après que le nouveau disque soit remplacé à chaud ou à froid, cela prend des jours pour pour qu'il se resynchronise.)2,10 $ pour RAID5 en miroir
Dans le SAN, c'est-à-dire.4,40 $ pour RAID1+0
Minimum pour les données de production, les journaux de transactions sauvegardés et les vidages nocturnes de la base de données.9,80 $ pour RAID1+0 répliqué
Vers une configuration SAN identique sur un autre site à l'épreuve des bombes. Arrêt de la production en quelques minutes ; presque aucune perte de transaction. -
Mémoire/Cache
Ok, Oracle n'en a pas mais les bases de données bancaires sérieuses ont des caches, et ils sont gérés. Quelle que soit la taille du cache, seules 62 % des lignes tiennent dans la même taille de cache. -
E/S logiques et physiques
Ce qui signifie 50 % d'E/S en plus pour lire la table ; à la fois en streaming dans le cache et en lecture sur disque.
-
-
-
Par conséquent, savoir si la requête fonctionne mieux ou moins bien isolément est une question académique. Dans le contexte de ce qui précède, le tableau est lent et fonctionne 62 % moins bien, tout le temps, à chaque accès. Et cela affecte tous les autres utilisateurs du serveur. La plupart des administrateurs de base de données ne se soucieront pas (je ne le ferais certainement pas) que le formulaire de sous-requête fonctionne à la moitié de la vitesse, car leur bonus est lié à l'acceptation de l'audit, et pas seulement aux performances du code.
-
En outre, il y a l'avantage supplémentaire de ne jamais avoir à revoir le code et à corriger les transactions en raison des anomalies de mise à jour.
-
Et les transactions ont moins de points à mettre à jour, donc elles sont plus petites; moins de serrures bloquantes, etc.
-
-
D'accord, cette discussion dans les commentaires est difficile. Dans ma réponse, j'ai détaillé et expliqué deux sous-requêtes. Il y a eu un malentendu :vous parliez de cette sous-requête (dans la clause WHERE, une sous-requête de table ) et je parlais de l'autre sous-requête (dans la liste des colonnes, une sous-requête scalaire ) quand j'ai dit qu'il fonctionne aussi vite ou plus vite. Maintenant que cela a été clarifié, je ne peux pas dire que la première requête ci-dessus (sous-requête dans la clause WHERE, une table) fonctionnera aussi vite que la deuxième requête (avec la colonne dupliquée); le premier doit effectuer 3 scans, là où le second n'effectue que 2 scans. (J'ose dire que le deuxième analysera la table.)
Le fait est qu'en plus du problème d'isolement, ce n'est pas une comparaison équitable, j'ai fait le commentaire sur les sous-requêtes scalaires. Je ne suggérerais pas qu'une requête en 3 scans soit aussi rapide ou plus rapide qu'une requête en 2 scans.
La déclaration que j'ai faite à propos de la sous-requête de la table à 3 balayages (que je cite ici) doit être prise dans son contexte complet (soit ce message dans son intégralité, soit ce qui précède). Je ne recule pas devant.
Je passe la moitié de ma vie à supprimer les alternatives illégales telles que les colonnes dupliquées, qui reposent sur la question des performances, les créateurs scandant le mantra selon lequel la table est lente, ils ont donc "dénormalisé pour les performances". Le résultat, prévisible avant de commencer, est une table deux fois plus petite, qui fonctionne deux fois plus vite globalement . La série Times est la question la plus courante ici (le lien renvoie à une autre question ; laquelle renvoie à une autre), mais imaginez le problème dans une base de données bancaire :
OpeningExposure
quotidien etClosingExposure
parSecurity
parHolding
parUnitTrust
parPortfolio
. -
Mais permettez-moi de répondre à une question qui n'a pas été posée. Ce type d'interaction est normal, pas rare lorsque l'on travaille avec des équipes de développement internes ; ça revient au moins une fois par mois. Un développeur à chaud a déjà écrit et testé son code, en utilisant une table avec une colonne dupliquée, il vole, et maintenant il est bloqué car je ne le mettrai pas dans la base de données.
Non, je vais le tester dans le contexte de l'ensemble du système et :
-
la moitié du temps, la table entre sans la colonne EndDate car il n'y a pas grand-chose à propos d'une requête d'une demi-seconde qui s'exécute maintenant en une seconde.
-
L'autre moitié du temps, les performances [table subquery] ne sont pas acceptables, j'implémente donc un indicateur booléen (bit) pour identifier
IsCurrent
. C'est bien mieux qu'une colonne dupliquée et offre 2 vitesses de balayage. -
Dans un million d'années, vous ne me ferez pas dupliquer une colonne ; ajouter 62 % à la taille de la table ; ralentir la table dans le contexte multi-utilisateur complet de 62 % ; et risquer d'échouer à un audit. Et je ne suis pas salarié, je ne reçois pas de prime.
Maintenant, cela vaudrait la peine d'être testé :requête avec une colonne dupliquée vs requête avec un
IsCurrent
indicateur, dans le contexte complet de l'utilisation globale des ressources. -
-
Smirkingman a soulevé un bon point. Et je vais le reformuler clairement, pour qu'il ne soit pas fragmenté et qu'ensuite l'un ou l'autre fragment soit attaqué. Veuillez ne pas rompre ceci :
Une base de données relationnelle,
normalisée par un modélisateur relationnel expérimenté,à la vraie cinquième forme normale
(pas d'anomalies de mise à jour ; pas de colonnes dupliquées),
avec une conformité relationnelle totale
(IDEF1X, notamment concernant la minimisation deId
clés primaires ; et donc ne pas paralyser la puissance du moteur relationnel)
résultera en plus de tables plus petites, une base de données plus petite,
avec moins d'indices,
nécessitant moins de jointures
(c'est vrai, plus de tables mais moins de jointures),
et il surpassera tout ce qui enfreint l'une de ces règles
sur le même matériel et l'entreprise plate-forme de base de données
(exclut les logiciels gratuits, MS, Oracle ; mais ne vous laissez pas arrêter),
dans le contexte complet de l'utilisation de l'OLTP en production
d'au moins un ordre de grandeur,
et il sera beaucoup plus facile à utiliser
et à modifier
(jamais besoin de "refactoring").Je l'ai fait au moins 80 fois. Deux ordres de grandeur ne sont pas rares, si je le fais moi-même, plutôt que de fournir le cadre à quelqu'un d'autre pour le faire.
Ni moi, ni les personnes avec qui je travaille ou qui me paient, ne me soucient de ce qu'une requête fera de manière isolée.