> Tech > 1.3 – Le cache des données

1.3 – Le cache des données

Tech - Par Renaud ROSSET - Publié le 24 juin 2010
email

Pour qu’un cache soit efficace il faut que les processus de mise en mémoire et de déchargement de la mémoire soient les plus optimisés possible. Pour ce faire, on a longuement étudié les mécanismes de lecture et d’écriture des disques et des mémoires et l’on en a conclu la chose

suivante : il ne sert à rien d’aller chercher une seule ligne d’une seule table sur un disque, car le temps perdu par les mécanismes matériels de déplacement des têtes de lecture seraient incommensurablement plus longs que l’envoi des quelques octets de la ligne.

On en a donc conclu que le mieux était de lire un paquet de données que l’on a estimé à 64 Ko au minimum et on lui a donné le nom d’extension13. Mais ces 64 Ko étant en fait trop grands pour constituer à eux seuls une ligne d’une table, on a parcellisé ces paquets en pages de données de 8 Ko, pages pouvant contenir chacune une ou plusieurs lignes d’une table. Voila pourquoi, la longueur maximale d’une ligne d’une table a longtemps été de 8 Ko, moins quelques octets "techniques"14. Pour refléter cette contrainte, la mémoire cache en RAM est une reproduction fidèle de l’organisation en page du fichier disque contenant les données. Autrement dit, le cache de données est lui aussi constitué de pages de 8 Ko, et les pages sont copiées du disque à la RAM à l’identique de manière binaire. La plupart du temps un page contiendra donc de multiples lignes… Mais lesquelles ?

C’est là qu’intervient la notion d’index…
• Soit la table n’a pas d’index et les lignes sont stockées dans l’ordre chronologique de leur insertion. Cela convient bien aux très petites tables15.
• Soit la table possède un index de type CLUSTER16 et les lignes sont triées dans l’ordre des données de cet index.
• Soit enfin la table ne possède pas d’index cluster et les lignes sont stockées dans l’ordre d’insertion, avec en sus une structure de données supplémentaire : l’index heap17 . Si vous avez créé une clef primaire sur une table avec les options par défaut, alors la création de cette clef primaire a entraîné la création d’un index cluster et les lignes de la table sont physiquement stockées de manière triée. Ceci n’est pas sans conséquence avec les problématiques de cache.

Pour bien en comprendre l’enjeu, prenons un exemple criant de vérité. Notre développeur a créé une table des factures et pour modéliser, sa clef a pris le parti de concaténer les quatre premières lettres du nom du client avec un numéro de comptage allant de 0000 à 9999. Bref, nos factures vont par exemple être stockées comme ceci dans la page de données : voir tableau 2. … du fait du tri physique lié au cluster. Or, il se trouve que notre client BRUN est décédé l’an dernier et que sa dernière commande remonte à 2003… De même BRASSAC n’a pas commandé depuis 2004.

En fait, dans cette organisation de stockage, le fait de demander la dernière facture du client BROUARD va faire remonter une page en mémoire contenant une grande quantité de lignes portant sur d’anciennes factures. Autrement dit, chaque fois que SQL Server va avoir à mettre en cache un lot de factures pour quelques clients encore actifs, ce modèle de données va ramener en mémoire de nombreuses factures obsolètes, en fait les lignes situées physiquement avant et après la seule ligne concernée dans la page de données. Soyons encore plus précis et voyons ce qui va se passer dans un tel modèle si l’on effectue la requête suivante :
SELECT *
FROM T_FACTURE
WHERE DATE_FACTURE BETWEEN DATEADD(DAY, -30, CURRENT_TIMESTAMP)
AND CURRENT_TIMESTAMP

Qui demande toutes les factures de ces trente derniers jours… Imaginons que la page contienne 250 lignes de factures en moyenne et que seul 3 factures par page sont réellement concernées. On considère en outre qu’il n’y a qu’une centaine de factures qui a été émise ces 30 derniers jours… Le calcul montre qu’il faudra monter en mémoire 34 pages de 8 Ko, soit 272 Ko. Ce n’est certes pas grand chose, mais comparé à une organisation de cluster dans laquelle on aurait pris pour composante de la clef, la date de facturation ou encore si la clef avait été constituée d’un auto incrément, on serait passé au plus à la lecture de deux pages, soit une optimisation de la mémoire d’au moins 17 fois (1700 %…). Voici comment on peut engorger un cache de données avec un modèle mal conçu.

Dans ce cas de figure, pour bénéficier d’une telle optimisation, il faudrait soit se débarrasser du mode cluster au profit du heap pour l’index sous jacent à la clef (si l’on veut conserver impérativement la composition de cette clef), sinon concevoir une clef plus astucieuse. Partant d’ailleurs, du même principe que le LRU, les données les plus récentes étant les plus utilisées, MS SQL Server préconise l’utilisation d’une clef auto incrémentée qui garantit un bon séquencement dans le temps. On voit tout de suite que dans un tel cas, les factures les plus récentes, donc les plus scrutées, sont situées toujours en fin de table, donc regroupées dans un minimum de pages, en fait les dernières de la table.

En ce sens, le choix de la clef et particulièrement la préconisation d’utiliser l’auto incrément minimise le cache des données. Troisième commandement : une bonne structure des clefs primaires et plus généralement, des index de la base, participe généralement à une économie drastique du cache des données.

Téléchargez cette ressource

Préparer l’entreprise aux technologies interconnectées

Préparer l’entreprise aux technologies interconnectées

Avec la « quatrième révolution industrielle », les environnements hyperconnectés entraînent de nouveaux risques en matière de sécurité. Découvrez, dans ce guide Kaspersky, comment faire face à cette nouvelle ère de vulnérabilité.

Tech - Par Renaud ROSSET - Publié le 24 juin 2010