Limites et performances d'Access

J'ai commencé à rédiger cette page alors que la version en cours était Access 2000. Les chiffres en rouge sont les chiffres trouvés sur le site de Microsoft lui-même, mais parfois corrigés ou affinés par d'autres sources sur le Web. Lorsque j'ai démontré un chiffre par ma propre expérience, je l'indique. EN bas de cette page, vous trouverez quelques indices de performance d'Access.

Mes tests ont été effectués sur :

Base de données en général

Taille d'un fichier MDB : 2 Go Toutefois, étant donné que votre base de données peut inclure des tables liées dans d'autres fichiers, sa taille totale n'est limitée que par la capacité de stockage disponible
Nombre d'objets dans un MDB : 32768
Nombre de caractères d'un nom d'objet : 64

Sécurité et travail en réseau

Nombre de caractères d'un mot de passe : 14 d'après Microsoft. Mais j'ai testé, et la réelle limitte (en tout cas pour la version 2003 est de 20 caractères)
Nombre de caractères d'un nom d'utilisateur ou de groupe : 20
Correct, j'ai testé
Nombre d'accès simultanés : 255

Je n'ai jamais eu l'occasion de tester une base de données avec plus de 10 accès concurrents, je ne peux donc pas confirmer ni infirmer cette info. Par contre, lorsque je fais la démonstration à mes élèves de l'utilisation en réseau d'une base Access, je leur demande de se placer dans une même table, sur un même enregistrement, et d'entrer chacun une info différente dans le même champ. Ensuite, je compte à rebours 3 ... 2 ... 1 ... GO ! Et tout le monde appuie sur SHIFT ENTER (Enregistrement) en même temps, pour obliger Access à Stresser. 8 fois sur 10, ça marche, le message d'erreur traditionnel "Un autre utilisateur à modifié les données" s'affiche, et tout rentre dans l'ordre, mais 20% du temps, la base se plante complètement, et nous devons redémarrer Access. Il est même certains cas ou la base de données est vraiment corrompue. Toutefois, je peux ne peux soupçonner Access au delà du raisonnable : la qualité, la structure et la vitesse du réseau sont peut être des facteurs déteminants également.

Tous les objets

Nombre de caractères de description d'un objet : 2048 (test personnel fait sur une table)

Nommage des objets

Concernant les noms de table, on peut y installer une table s'appelant :

üéàèöäüÂÑñ_-*€/:;ç%&()ù+\<>@¦|°§£{}

Les seuls caractères interdits que j'ai repéré sont les crochets ouvrants et fermant, ainsi que le . [ ] .

On pourrait penser que les autres objets d'Access suivent les mêmes règles, mais non. Les requêtes oui, mais les formulaires et les états ne peuvent pas comporter le signe ; (point virgule) par exemple. Je dis par exemple, parce qu'il est possible que d'autres caractères soient interdits.

Je me suis livré à un petit exercice de style : j'ai créé un formulaire avec assistant basé sur la table üéàèöäüÂÑñ_-*€/:;ç%&()ù+\<>@¦|°§£{}, qui comporte donc des caractères interdits tels que le point virgule, et à la fin de l'assistant, il me propose de nommer ce formulaire üéàèöäüÂÑñ_-*€/:;ç%&()ù+\<>@¦|°§£{}. J'accepte, et là, il accepte de l'enregistrer.

Pour résumer avec l'exemple du point virgule :

On peut avoir une table s'appelant ; OUI
On peut avoir une requête s'appelant ; OUI
On peut avoir un formulaire s'appelant ; NON (ou alors en rusant comme décrit plus haut)
On peut avoir une macro s'appelant ; OUI
On peut avoir un module s'appelant ; NON

Relations

Nombre de relations en vigueur 32 par table moins le nombre d'index de la table pour les champs ou combinaisons de champs qui ne font pas l'objet de relations

Tables

Nombre de tables ouvertes simultanément 2 048. Le nombre réel de tables peut être inférieur, certaines tables étant ouvertes par Microsoft Access de façon interne. Non testé personnellement
Nombre de caractères d'un nom de table : 64

Nombre de caractères dans un enregistrement : 4'000 (+ les champs objet OLE et Mémo)

Effectivement, il n'est pas possible de nommer une table avec plus de caractères. Voici le plus long nom de table possible :

Nombre de caractères d'un nom de champ : 64

Il est simplement impossible d'en mettre plus. Voici le plus long champ possible :

Nombre de caractères dans la description d'un champ : 2048
Nombre de champs dans une table : 255
Taille d'une table : 1 Gb

 

Microsoft ne précise pas le nombre de tables maximum pour une base de données (la seule info est 32768 objets). J'ai créé ce petit module qui crée 1300 tables :

Sub Creer1300Table()
  Dim NouvelleTable As DAO.TableDef
  Dim NouveauChamp As DAO.Field
  For Ctr = 1 To 1300
    Set NouvelleTable = CurrentDb.CreateTableDef("T_Dyn" & Ctr)
    Set NouveauChamp = NouvelleTable.CreateField("ChampBidon", DB_SINGLE)
    NouvelleTable.Fields.Append NouveauChamp
    CurrentDb.TableDefs.Append NouvelleTable
  Next
Set NouvelleTable = Nothing
Set NouveauChamp = Nothing
End Sub

Il n'y a pas eu de problème. J'aurais certainement pu en créer beaucoup plus. Par contre, petit détail : les premières tables sont créées beaucoup plus rapidement que les dernières. Au départ, il a eu le temps de créer 83 tables en une seconde (Athlon 1.4 GHz, 1Gb RAM)

Mais à la fin, les performances se dégradent au point de 2 tables par secondes :

A ma grande surprise, le compactage après création de ces 1300 tables n'a pas pris un temps fou (7 secondes). L'ouverture et la fermeture de la base se font quasi-instantanément.

255 champs par table : essai concluant !

J'ai également testé si on arrive bien à 255 champs dans une seule table, la réponse est OUI. 255, pas un de plus. Le code VBA suivant permet de le tester :

Sub Creer255Champ()
   Dim NouvelleTable As DAO.TableDef
   Dim NouveauChamp As DAO.Field
   Set NouvelleTable = CurrentDb.CreateTableDef("T_Champ")
   For Ctr = 1 To 255
     Set NouveauChamp = NouvelleTable.CreateField("Champ" & Ctr, DB_SINGLE)
     NouvelleTable.Fields.Append NouveauChamp
   Next
   CurrentDb.TableDefs.Append NouvelleTable
   Set NouvelleTable = Nothing
   Set NouveauChamp = Nothing
End Sub

Contenu des champs

Nombre de caractères d'un champ texte : 255 (Absolument correct, j'ai testé.)
Nombre de caractères d'un champ mémo : 65535 lors de la saisie des données au moyen de l'interface utilisateur;
1 gigaoctet lors de leur saisie par programmation.
Taille d'un champ OLE : 1 Gb
Nombre d'index dans une table : 32
Nombre de champs dans un index : 10

Effectivement, pas question de créer une clé combinée sur plus de 10 champs. Par contre 10 champs, passent très bien :

Nombre de caractères d'un message de validation : 2048
Nombre de caractères d'une règle de validation : 2048
Nombre de caractères d'une description de table ou de champ : 255
(Mes tests acceptent jusqu'à 2048 caractères)
Nombre de caractères d'un enregistrement (mis à part Mémo et OLE) : 2000
Ceci est une simple recopie d'une page Web. J'aimerait bien voir un exemple d'un champ non mémo ou OLE qui fait plus de 255 caractères...
Nombre de caractères de la valeur définissant une propriété d'un champ : 255
(Mes tests acceptent jusqu'à 2048 caractères)

Requêtes

Nombre de tables dans une requête : 32

Absolument exact : 32 tables, Access ne dit rien. Dès 33 tables, lors du lancement de la requête, on a un message d'erreur "Requête trop complexe" :

Nombre de champs dans une requête : 255

Attention : c'est effectivement la limite décrite dans l'aide Access. Toutefois, lors de mes tests, il m'a d'abord laissé passé plus de 700 champs, mais par la suite avec un deuxième test plus précis, j'ai effectivement un message d'erreur dès le 256ème champ, que les champs proviennent d'une table unique ou de plusieurs tables.

Nombre de champs de tri dans une requête : 10

Je suis pourtant arrivé à mettre 21 colonnes en tri l'une à côté de l'autre (J'aurais certainement pu en mettre encore plus. La requête s'est bien lancée, et bien enregistrée. Le code SQL s'est même bien enregistré :

SELECT T_Champ.Champ1, T_Champ.Champ2, T_Champ.Champ3, T_Champ.Champ4, T_Champ.Champ5, T_Champ.Champ6, T_Champ.Champ7, T_Champ.Champ8, T_Champ.Champ9, T_Champ.Champ10, T_Champ.Champ11, T_Champ.Champ12, T_Champ.Champ13, T_Champ.Champ14, T_Champ.Champ15, T_Champ.Champ16, T_Champ.Champ17, T_Champ.Champ18, T_Champ.Champ19, T_Champ.Champ20, T_Champ.Champ21
FROM T_Champ
ORDER BY T_Champ.Champ1, T_Champ.Champ2, T_Champ.Champ3, T_Champ.Champ4, T_Champ.Champ5, T_Champ.Champ6, T_Champ.Champ7, T_Champ.Champ8, T_Champ.Champ9, T_Champ.Champ10, T_Champ.Champ11, T_Champ.Champ12, T_Champ.Champ13, T_Champ.Champ14, T_Champ.Champ15, T_Champ.Champ16, T_Champ.Champ17, T_Champ.Champ18, T_Champ.Champ19, T_Champ.Champ20, T_Champ.Champ21;

Mais je n'avais pas suffisamment de données pour tester si le tri au delà des 10 premièpres colonnes s'effectuait correctement.

Nombre de niveaux de requêtes imbriquées : 50
Nombre de caractères dans une cellule de grille d'interrogation
(QBE je suppose) : 1024
Nombre de AND dans une clause WHERE ou HAVING : 40
Nombre de caractères d'une instruction SQL : 64000 env.

Formulaires et états

Nombre de caractères d'une étiquette : 2048 Exact. J'ai testé. 2048, pas un de plus n'est possible.
Nombre de caractères d'une zone de texte : 65535.
Oui, mais on ne peut pas écrire physiquement plus de 2048 caractères fixes, comme ceci : ="1234567890123... etc. ce serait seulement pour accueillir un champ mémo, ou une concaténation de plusieurs gros champs.
Nombre total de contrôles et de sections : 754

Effectivement, lorsqu'on dépasse ce nombre, Access prévient qu'on ne peut plus créer de contrôle ssu ce formulaire, mais il le fait quand même. Les copier coller de bien plus de contrôles sont chaque fois précédés de cet avertissement, mais il laisse faire, et enregistre le formulaire correctement.

Largeur d'un formulaire ou d'un état : 22 pouces (55.87 cm) Correct : J'ai testé.
Hauteur d'une section : 22 pouces (55.87) cm
Correct : J'ai testé.
Hauteur de toutes les sections et de leurs en-têtes (en mode création) : 200 pouces (508 cm)
Nombre de niveaux de formulaires ou d'états imbriqués : 3
(Formulaire, Sous formulaire et sous-sous-formulaire)

Etats seulements

Limites des en-têtes et pieds : 1 en-tête/pied d'état | 1 en-tête/pied de page | 10 en-têtes/pieds de groupe
Nombre de pages imprimables dans un état : 65535.
Le maximum que j'ai testé était un peu plus de 17'000 (voir la fin de cette pages), mais plus sont évidemment possibles.

Macros

Nombre d'actions dans une macro : 999 Correct, j'ai testé.
Nombre de caractères d'une condition : 255
Nombre de caractères d'un commentaire : 255

Nombre de caractères d'un argument d'action : 255

Modules

Modules (y compris les formulaires et états dont la propriété AvecModule (HasModule) a pour valeur Vrai (True) : 1000

Performances

J'ai créé le code VBA suivant pour créer artificiellement 1 million d'enregistrements dans une table T_Contact. SI vous désirez renouveler l'expérience, vous devez avoir a disposition une table (vide) contenant 3 Champs : IDContact : NuméroAuto, NomContact : Texte 20, Prenom : Texte 20. Recopiez alors le code VBA suivant dans un module, et exécutez-le. Sur ma configuration (description en début de page), j'ai chronométré 1 minute 20. :

Sub CreerPleinDenregistrements()
  Dim Chaine As String, Chaine2 As String, Ctr As Integer, Compteur As Long, NbLettre As Integer
  Dim MaTable As DAO.Recordset
  Set MaTable = CurrentDb.OpenRecordset("T_Contact", dbOpenDynaset)
  For Compteur = 1 To 1000000
    NbLettre = 3 + (8 * Rnd(1))
    NbLettre2 = 3 + (8 * Rnd(1))
    For Ctr = 1 To NbLettre
      Chaine = Chaine & Chr(Int(26 * Rnd(1)) + 97)
    Next
    For Ctr = 1 To NbLettre
      Chaine2 = Chaine2 & Chr(Int(26 * Rnd(1)) + 97)
    Next
    MaTable.AddNew
      MaTable("NomContact") = Chaine
      MaTable("Prenom") = Chaine2
    MaTable.Update
    Chaine = ""
    Chaine2 = ""
  Next
  MaTable.Close
  Set MaTable = Nothing
End Sub

Effacement de 100'000 enregistrements parmi 1'000'000 : 27 secondes
Temps d'ouverture de la table : 30 secondes
Temps d'importation de cette table dans une base de données vide : 16 secondes

Les tests suivants sont maintenant effectués dans une base vide comprenant seulement cette table importée :

Taille de cette nouvelle base : 41'244 Ko (Soit une quarantaine de Mégas !)
Temps d'ouverture de la table dans la nouvelle base de données qui ne contient rien d'autre : instantané
Tri par le champ Nom (Champ texte non indexé) : 30 secondes
Temps de compactage (Outils/Utilitaires de base de données) : 12 secondes
Taille de la base après compactage : 41'244 Ko (Aucun bénéfice)
Mise en Index, avec doublons du champ NomContact : 12 secondes
Tri alphabétique ou tri inverse sur ce champ maintenant indexé : instantané
Taille de la base après la mise en place de cet index: 53'744 Ko
Le compactage juste maintenant donne un résultat étonnant : 53'772 Ko !
Bien que le champ soit indexé, le filtre demandé sur le nom (en l'occurrence *aaa*) demande 6 secondes de traitement.

Le temps de traitement pour le même filtre *aaa* demandé sur prénom, qui n'est pas indexé demande aussi 6 secondes. L'index grossit donc la taille de la base de données, mais n'est utile que pour les tris. Pas pour les filtres.

J'ai créé une requête avec assistant "Trouver les doublons", pour chercher les doublons sur le champ indexé NomContact. Temps : 2 minutes 07. Une fois que j'avais dans la 1ère colonne les noms en double et le nombre de doublons dans la 2ème colonne, j'ai demandé à la volée (bouton droit de la souris) un tri décroissant sur le nombre de doublons. Je l'ai laissé tourner 5 minutes et je l'ai arrêté ave CTRL ALT DEL. Access s'est donc cru investi de la mission de tout recommencer à 0.

Création d'un formulaire instantané/tableau basé sur T_Contact : 5 secondes

Les tris dans le champ NomContact sont aussi instantanés que dans la table.

J'ai ensuite créé un état tout simple, sans assistant, avec une seule section (Détail). J'y ai placé le champ Nom. L'aperçu avant impression a été instantané. Par contre l'arrivée sur la dernière page a demandé 58 secondes. plus de 17'000 pages ont été générées :

L'enregistrement de l'état est instantané.

Pa rcontre lorsqu'il s'agit d'un état avec regroupement, même sommaire, c'est une autre musique :

Je l'ai lancé l'aperçu avant impression, et après 6 minutes d'attente, je me suis résolu à l'arrêter. Par contre, si on se contente de l'enregistrer en mode Création, c'est instantané.