Alors, je vais en remettre une petite couche.
Evidement, cela s'applique à mon expérience, sur un projet précis. Il va donc de soit que les contrôles que je préconisent ne s'appliquent pas forcément.
Déjà, dans un premier temps, au niveau de l'ASP :
- Utilisation de la clause "Option Explicit" en haut de toutes les pages
- Ouverture d'une unique connection par page, et fermeture de cette dernière dans toutes les pages (les connections qui restent ouvertes, c'est très courant en ASP, et ça coûte très cher en terme de mémoire, puis en terme de vitesse pure -quand ça se met à swaper c'est fini )
- Création du MINIMUM d'objets ADODB.RecordSet et ADODB.Command : dès qu'il ne sont plus utilisés, les fermer proprement, puis les réutiliser au lieu de créer de nouvelles variables inutiles.
- Ne jamais utiliser "rs.Open" et encore moins "cnx.Execute" ! TOUJOURS passer par un objet ADODB.Command pour écrire dans la base ou lire des informations. Ca change les performances du tout au tout, et c'est en plus se blinder contre d'éventuelles tentatives de "SQL Injection".
- Oublier définitivement les variables de session. Leur préférer l'utilisation de Cookies de session (cookies avec une date d'expriration antérieure à leur création). Ne pas hésiter à gaspiller des requêtes pour rechercher des données qu'on aurait pu mettre en session. Le gain par l'abandon de ces dernières sera de toute façon suppérieur (bien penser à les désactiver dans IIS). L'utilité de se passer des variables de session, c'est surtout :
1/ Economiser une quantité non négligeable de mémoire sur le serveur
2/ Economiser en vitesse pure (c'est pas terrible d'avoir un objet de connection avec tout le cache ce cela implique en mémoire, surtout que ça force le SGBD à contrôler d'éventuels locks)
3/ Ca améliore la lisibilité du code et sa maintenance (les sessions qui tombent du ciel et expirent en plein milieu d'un process complexe, c'est vraiment la tannée à débuger)
- Oublier aussi les variables d'application, pour la même raison. Même la chaîne de connection ne doit pas s'y trouver : préférer un fichier d'include avec ce genre d'informations en constante.
- Oublier les passages d'objets entre fonctions. Ou les minimuser au maximum. Genre les fonction GetRs("select toto from truc" ) qui retournent un recordset sont à banir !
- Ne pas hésiter à multiplier les fonctions quite à les rendre très courtes et avec des niveaux d'imbrication plus élevé. Même si cela représente une légère perte de performances, cela évite généralement des usines à gaz et la duplication de code dans des includes titanesques (et ça par contre c'est mortel de faire un include de 8 Mo, j'ai testé pour vous)
- Utiliser au maximum des procédures stockées et des vues pour accéder à la base : le gain de performance lors de leur exécution est énorme, surtout en utilisation intensive, mais surtout, ça permet de gérer les droits d'accès à la base de façon plus précise : dans une application idéale, l'utilisateur qui sert au site doit avoir un DENY sur tous les objets de la base, mise à part aux procédures stockées où il aura la permission EXEC uniquement. (ça change rien aux perfs, mais niveau sécurité, ça permet de s'affranchir d'un grand nombre de mécanismes qui serait utilisés sur le serveur, et surtout, c'est plus propre, donc tant qu'on y est, autant le faire).
Pour ce qui est de la base de données :
- Déjà, c'est simple : refaire l'analyse point par point, à la fois pour les tables volumineuses, mais aussi pour les tables intensément utilisées. Genre t'as 200 users inscrits... Si tu vérifies le mot de passe à chaque page, t'as plus intérêt à optimiser cette table que celle de l'historique des commandes qui ne sera consulté que par deux gars dans la journée.
- Limiter au maximum les données redondantes, et ne pas hésiter à multiplier les jointures (c'est faux, une jointure NE CONSOMME RIEN en terme de performances ou mémoire... bien moins qu'un index non unique qui porte sur des milliers de doublons inutiles)
- Ne pas hésiter à stocker quelques valeurs calculées. Genre pour un site marchant, ne pas hésiter à stocker dans l'entête du basket son total : il ne change pas à chaque page, donc c'est idiot de devoir rechercher tous les produits qu'il contient afin de retrouver le montant total.
- Toujours en ce qui concerne la dénormalisation, ne pas hésiter non plus à plancher sur des vues "de la mort qui tue" afin de simplifier énormément des requêtes (genre t'as une gestion de composés/composants avec des prix unitaires calculés, ne pas hésité à faire ces traîtements dans une vue).
- En ce qui concerne l'installation du SGBD, suivre scrupuleusement les recommandations de l'éditeur. A savoir, pour la plupart :
1/ Un disque physique pour l'OS uniquement
2/ Un disque physique pour la SWAP uniquement
3/ Un disque physique pour l'applicatif du SGBD uniquement (à la limite, tu peux le mettre sur le premier)
4/ Un disque physique pour la base de données (données)
5/ Un disque physique pour les index (quand c'est possible, avec SQL Server par exemple, c'est pas évident puisque les PK sont obligatoirement stockées dans le même fichier que la table)
6/ Un disque physique pour les log de trasactions
=> Eh oui : 6 disques dur, pas moins ! Le RAID, vous en mettrez si vous avez encore des disques en rab. (ne pas oublier une solution de backup horraire incrémentale si les données et les logs ne sont pas sur un RAID redondant)
- Repenser tous les index. La présence de vues et procédures stockées à la place de requêtes perdues dans le code est un atout non négligeable pour cette étape !
Voilà, je n'entre pas plus dans le détail, mais rien qu'avec ça, y'a de quoi améliorer considérablement les performances, surtout si nombre de ces points n'ont pas été suivis au départ.
Et je redis encore et toujours : si le serveur d'application (IIS) peut tourner sur un serveur low cost d'entrée de gamme (une machine perso actuelle est infiniment plus puissante que nécessaire pour un serveur qui se tape des milliers de hits par seconde), le serveur pour le SGBD, lui, doit être bichonné ! Au moins deux canaux SCSI, au grand minimum, 2 Go de mémoire (c'est pas pour ce que ça coûte...) et si possible une architecture bi-processeur (une vraie, pas du HT) pour avoir une montée en charge plus linéaire.
Message édité par MagicBuzz le 19-09-2006 à 19:48:15