Optimisation des applications Blackfish SQL

De RAD Studio (Français)

Remonter à Rubriques d'aide Blackfish SQL

Cette section présente les méthodes qui permettent d'améliorer les performances, la fiabilité et la taille des applications Blackfish SQL. A moins que ce ne soit spécifié autrement, DataStoreConnection fait référence à une classe DataStoreConnection ou à un objet DataStore utilisé pour ouvrir une connexion dans un fichier Blackfish SQL.

Sommaire

Chargement rapide des bases de données

Voici quelques astuces pour améliorer les performances de votre application au chargement des bases de données :

  • Utilisez des instructions ou des commandes préparées chaque fois que c'est possible. Si le nombre de paramètres change d'une insertion à l'autre, effacez les paramètres avant de définir les nouveaux.
  • Créez la table sans clés primaires, ni clés étrangères, ni index secondaires. Chargez la table, puis créez les clés primaires, clés étrangères et index secondaires dont vous avez besoin.

Optimisation du chargement des bases de données spécifique à Java

Utilisez la classe DataExpress TextDataFile pour importer des fichiers texte. Son analyseur est rapide et elle peut charger les données rapidement. Vous devez définir le store StorageDataSet par une DataStoreConnection et la propriété StoreName par le nom de votre table dans la base de données Blackfish SQL. Lorsque vous chargez une nouvelle base de données :

  1. Créez d'abord la base de données non transactionnelle.
  2. Pendant que la base de données est non transactionnelle, utilisez un composant DataExpress StorageDataSet.addRow ou TextDataFile pour charger la base de données.
  3. Une fois que la base de données est chargée, utilisez la propriété DataStore.TxManager pour la rendre transactionnelle.

Cette technique permet de charger la base de données deux ou trois fois plus rapidement.

Recommandations générales

Cette section propose quelques conseils pour améliorer les performances des applications Blackfish SQL.

Fermeture correcte de la base de données

Si une base de données n'est pas fermée correctement, il y aura un délai la prochaine fois qu'un processus l'ouvrira. Cela est dû au fait que Blackfish SQL a besoin de 8 à 10 secondes pour vérifier qu'aucun autre processus n'a ouvert la base de données. Pour vérifier qu'une base de données a été correctement fermée, assurez-vous que toutes les connexions devenues inutiles sont fermées. S'il est difficile de vérifier que toutes les connexions sont fermées, utilisez une connexion avec les droits de l'administrateur pour appeler la procédure stockées intégrée DB_ADMIN.CLOSE_OTHER_CONNECTIONS qui vérifie que toutes les autres connexions sont fermées.

La fermeture de toutes les connexions présente un autre avantage, en libérant la mémoire allouée au cache du Blackfish SQL.

Actuellement, les bases de données non transactionnelles peuvent être accédées par SQL uniquement si la propriété de lecture seule de la base de données est définie par true. Mais, les JavaBeans DataExpress peuvent effectuer des opérations d'écriture sur une base de données non transactionnelle.

La fermeture d'une base de données Blackfish SQL assure que toutes les modifications sont enregistrées sur disque. Un thread démon pour toutes les instances DataStoreConnection ouvertes enregistre constamment les données modifiées en mémoire cache. (Par défaut les données modifiées sont enregistrées toutes les 500 millisecondes). Si vous quittez la machine virtuelle Java directement, sans fermer la base de données, le thread démon n'a pas la possibilité d'enregistrer le dernier ensemble de modifications. Cela présente un petit risque de détérioration d'une base de données Blackfish SQL si elle n'est pas transactionnelle.

Une base de données Blackfish SQL transactionnelle ne peut pas perdre de données, mais le gestionnaire de transactions annule toutes les modifications non validées.

Fermeture des bases de données spécifique à Java

Si votre application utilise des composants JavaBean DataExpress, fermez tous les StorageDataSet dont la propriété store est définie par une DataStoreConnection lorsque vous avez fini de les utiliser. Cela libère les ressources Blackfish SQL associées au StorageDataSet et lui permet d'éliminer ses données périmées.

Vous pouvez utiliser la méthode DataStore.shutdown() pour vérifier si toutes les connexions à une base de données ont été correctement fermées.

Optimisation du cache disque de Blackfish SQL

La taille maximale par défaut du cache pour une base de données Blackfish SQL est de 512 blocs. La taille par défaut d'un bloc est de 4096 octets. La mémoire cache atteint donc une capacité maximale d'environ 2 Mo (512*4096). Notez que cette mémoire est allouée selon les besoins. Dans quelques rares situations, lorsque tous les blocs sont utilisés, le cache peut dépasser la limite des 512 blocs. Vous pouvez utiliser la propriété DataStore.MinCacheSize pour spécifier la taille minimale du cache.

REMARQUE : Ne modifiez pas sans raison la taille du cache de la base de données. Vérifiez au préalable qu'agir ainsi augmentera bien les performances de votre application.

Avant de modifier la taille du cache Blackfish SQL, réfléchissez aux points suivants :

  • Les caches OS modernes ont généralement de hautes performances. Dans de nombreux cas, augmenter la taille du cache Blackfish SQL n'améliore pas significativement les performances mais utilise plus de mémoire.
  • Il n'existe qu'un seul cache disque Blackfish SQL pour toutes les bases de données Blackfish SQL ouvertes dans le même processus. Lorsque toutes les bases de données Blackfish SQL sont arrêtées, la mémoire du cache disque global est libérée.
  • Pour les périphériques portables avec de faibles quantités de mémoire, définissez la propriété DataStore.MinCacheSize par une valeur plus petite, par exemple 96.

Optimisation de l'accès aux fichiers

Les bases de données Blackfish SQL exécutent la majorité des opérations de lecture/écriture avec les quatre types de fichiers suivants :

  • Le fichier de la base de données Blackfish SQL elle-même (l'extension de ce fichier est .jds) tel que spécifié par la propriété DataStore.FileName
  • Les fichiers historiques transactionnels Blackfish SQL (l'extension de ces fichiers est LOGAnnnnnnnnnn, où n est un chiffre) tels que spécifiés par la propriété TxManager.ALogDir
  • Les fichiers temporaires utilisés par les grandes opérations de tri, tels que spécifiés par la propriété DataStore.TempDirName
  • Les fichiers temporaires .jds utilisés pour les résultats des requêtes SQL, tels que spécifiés par la propriété DataStore.TempDirName

Vous pouvez améliorer les performances en commandant à Blackfish SQL de placer les fichiers mentionnés précédemment sur différentes unités de disque.

Stockage des fichiers

Voici quelques conseils de gestion du stockage des fichiers qui peuvent améliorer les performances de vos applications :

  • Il est particulièrement important de placer les fichiers historiques sur une unité de disque séparée. Notez que les fichiers historiques sont généralement ajoutés dans un ordre séquentiel et que leur contenu doit subir une écriture forcée sur disque pour les validations (commit). Par conséquent, il est avantageux de disposer d'une unité de disque pouvant accomplir rapidement des opérations d'écriture.
  • Sur les plates-formes Win32, les performances peuvent être améliorées si vous placez les fichiers historiques de Blackfish SQL dans un répertoire distinct. Le stockage de nombreux fichiers autres que les fichiers historiques dans le répertoire des fichiers historiques peut ralentir les performances des opérations de validation. Ce conseil peut être suivi pour des plates-formes autres que Windows NT/2000/XP.
  • N'oubliez pas de défragmenter régulièrement les systèmes de fichiers de vos unités de disque. Cette pratique est surtout importante pour l'unité de disque stockant les fichiers historiques, car Blackfish SQL effectue sur ce fichier un grand nombre d'opérations séquentielles de lecture/écriture.
  • Sur les plates-formes Win32, envisagez d'utiliser un système de fichiers FAT32 et une taille de cluster assez confortable, 64 Ko par exemple, pour le disque sur lequel sont écrits les fichiers historiques.

Options d'écriture dans le cache disque d'une base de données non transactionnelle

Remarque : Cette section s'applique uniquement à Blackfish SQL pour Java, qui utilise les composants JavaBean DataExpress.

Utilisez la propriété saveMode du composant DataStore pour contrôler la fréquence d'écriture sur disque des blocs du cache. Cette propriété ne s'applique qu'aux bases de données Blackfish SQL non transactionnelles. Voici les valeurs correctes de la méthode :



 0 

Laisser le thread démon gérer toutes les écritures de cache. Cette valeur offre les meilleures performances mais aussi le plus grand risque de corruption.

 1 

Enregistrer immédiatement lorsque les blocs sont ajoutés ou supprimés ; laisser le thread démon gérer toutes les autres modifications. Il s'agit du mode par défaut. Les performances sont presque aussi bonnes qu'avec saveMode(0).

 2 

Enregistrer immédiatement toutes les modifications. Utiliser cette valeur chaque fois que vous déboguez une application utilisant un composant DataStore.



A l'inverse des autres propriétés de DataStore, saveMode peut être modifiée quand la connexion est ouverte. Si vous utilisez par exemple une DataStoreConnection, vous pouvez accéder à la valeur via la propriété dataStore :


DataStoreConnection store = new DataStoreConnection();
...
store.getDataStore().setSaveMode(2);

Notez que cela modifie le comportement de tous les objets DataStoreConnection accédant à ce fichier de base de données Blackfish SQL particulier.

Réglage de la mémoire

Vous pouvez régler l'utilisation de la mémoire d'un certain nombre de manières. Sachez que demander trop de mémoire peut s'avérer aussi mauvais que d'en avoir trop peu.

  • Vous pouvez essayer d'augmenter la propriété ConnectionProperties.MinCacheBlocks, qui contrôle le nombre minimal de blocs mis en mémoire cache.
  • La propriété ConnectionProperties.MaxSortBuffer contrôle la taille maximale du tampon mémoire utilisé pour les tris en mémoire. Les tris dépassant cette taille de tampon mémoire utilisent un algorithme de tri plus lent basé sur le disque.

Réglage de la mémoire spécifique à Java

Le tas Java a tendance à résister à croître au-delà de sa taille initiale, en forçant une élimination fréquente des données périmées avec toujours une petite taille de tas libre. Utilisez l'option JVM -Xms pour spécifier une plus grande taille de tas initiale. Il y a souvent un avantage certain à donner la même valeur aux paramètres JVM -Xms et -Xmx.

Autres astuces pour améliorer les performances

Voici quelques conseils pour améliorer les performances :

  • Définir la propriété ConnectionProperties.TempDirName, utilisée par le moteur de requête, par un répertoire se trouvant sur une autre unité de disque (rapide) peut aider.
  • Essayez de changer la fréquence du point de vérification pour le gestionnaire de transactions. Augmenter la valeur de cette propriété peut améliorer les performances mais aussi ralentir les récupérations après panne. Cela peut être fait par SQL, à l'aide de la procédure stockée intégrée DB_ADMIN.ALTER_DATABASE. Dans Blackfish SQL pour Java, vous pouvez utiliser JdsExplorer pour définir cette propriété en choisissant TxManager > Modifier.

Optimisation des applications transactionnelles

Le gain en fiabilité et en flexibilité apporté par l'utilisation de bases de données Blackfish SQL transactionnelles se fait au détriment de certaines performances. Vous pouvez réduire cet inconvénient de différentes manières, comme décrit dans les sections suivantes.

Utilisation des transactions en lecture seule

Pour les transactions effectuant des lectures et non des écritures, les améliorations de performance significatives peuvent être réalisées en utilisant une transaction en lecture seule. La propriété readOnly de connexion contrôle si une transaction se trouve en lecture seule. Le JavaBean DataStoreConnection de Blackfish SQL pour Java dispose d'une propriété readOnlyTx pour permettre les transactions en lecture seule.

Les transactions en lecture seule fonctionnent en simulant une capture de la base de données Blackfish SQL. Cette capture ne voit que les données des transactions validées au moment où la transaction de lecture seule commence. Cette capture, créée à l'ouverture de DataStoreConnection, est actualisée à chaque appel d'une méthode commit.

Les transactions en lecture seule présentent un autre avantage, celui de ne pas être bloquées par des écritures ou par d'autres lectures. La lecture et l'écriture requièrent généralement toutes les deux un verrouillage. Mais comme une transaction en lecture seule utilise une capture, elle n'a pas besoin de verrouillage.

Vous pouvez optimiser davantage l'application en spécifiant une valeur pour la propriété readOnlyTxDelay. La propriété readOnlyTxDelay spécifie l'ancienneté maximale (en millisecondes) d'une capture existante que la connexion puisse partager. Lorsque la propriété n'a pas la valeur zéro, les captures existantes sont recherchées (de la plus récente à la plus ancienne). Si l'ancienneté de l'une d'elles est inférieure à readOnlyTxDelay, elle est utilisée et une nouvelle capture n'est pas réalisée. Par défaut, cette propriété a une valeur de 5000 millisecondes.

Utilisation du mode validation logicielle

Si vous activez le mode validation logicielle dans la propriété SoftCommit, le gestionnaire de transactions continue à enregistrer un historique des transactions validées mais il n'utilise pas de mécanisme d'écriture synchrone pour les validations. Lorsque la validation logicielle est activée, le cache du système d'exploitation peut mettre dans le tampon les écritures de fichiers des transactions validées. Généralement, le système d'exploitation finit en quelques secondes l'écriture sur disque des blocs brouillés. La validation logicielle améliore les performances mais ne garantit pas la durabilité des dernières transactions validées. Vous pouvez définir la propriété SoftCommit en appelant la procédure stockée intégrée DB_ADMIN.ALTER_DATABASE.

Désactivation de l'historique des états pour les fichiers historiques de transactions

Une désactivation de l'historique des messages d'état peut aussi améliorer les performances. Pour cela, initialisez à false la propriété RecordStatus. Vous pouvez définir la propriété RecordStatus en appelant la procédure stockée intégrée DB_ADMIN.ALTER_DATABASE.

Réglage des performances du contrôle des accès simultanés avec Blackfish SQL

Voici quelques conseils pour optimiser les performances des opérations de contrôle des accès simultanés avec Blackfish SQL :

  • Choisissez le niveau d'isolation le plus bas sous lequel votre application puisse fonctionner. Les faibles isolations posent les verrous les moins nombreux et les moins puissants.
  • Regroupez les instructions multiples dans une seule transaction. Les connexions passent par défaut en mode validation automatique après l'exécution de chaque instruction.
  • Validez les transactions aussi tôt que possible. La majorité des verrous ne sont libérés qu'au moment où la transaction est validée (commit) ou annulée (rollback).
  • Réutilisez les objets instruction ou commande chaque fois que c'est possible, ou encore mieux, utilisez des instructions ou des commandes préparées quand c'est possible.
  • Fermez toutes les instructions ou commandes, tous les ensembles de résultats ou lectures, et tous les objets connexion lorsqu'ils ne sont plus utilisés. Notez que les objets ensemble de résultat ou lecture uni-directionnels sont automatiquement fermés lors de la lecture de la dernière ligne.
  • Utilisez des transactions en lecture seule pour les états dont l'exécution dure longtemps ou pour les opérations de sauvegarde en ligne. Utilisez la méthode DB_ADMIN.COPYDATABASE pour les sauvegardes en ligne. La lecture seule fournit une vue cohérente (sérialisable), du point de vue des transactions, des tables utilisées. Les transactions ne posant pas de verrou, aucun dépassement du délai de libération d'un verrou ni verrouillage mortel ne peut se produire. Voir la section Utilisation des transactions en lecture seule.
  • La maintenance d'une vue en lecture seule a un coût en temps système. En conséquence, plusieurs transactions peuvent partager la même vue en lecture seule. La propriété ConnectionProperties.ReadOnlyTxDelay spécifie l'ancienneté maximale de la vue en lecture seule au moment où démarre la transaction en lecture seule permettant de l'utiliser. La validation d'une transaction pour une connexion en lecture seule actualise sa vue de la base de données. Notez qu'une transaction en lecture seule utilise les fichiers historiques transactionnels pour maintenir les vues. En conséquence, les connexions en lecture seule doivent être fermées dès qu'elles ne sont plus nécessaires.

Utilisation du traitement multithread

La capacité de traitement des transactions en écriture peut augmenter avec le nombre de threads utilisés pour effectuer les opérations car chaque thread peut diviser le temps système des opérations de validation via le support de la "validation de groupe" apporté par Blackfish SQL.

Allègement des ressources déployées pour les applications Blackfish SQL pour Java

Lors du déploiement d'une application Blackfish SQL, certaines classes et certains fichiers graphiques peuvent être exclus car ils ne sont pas utilisés.

  • Si Blackfish SQL est utilisé sans employer le pilote JDBC, excluez les classes suivantes :
    • com.borland.datastore.Sql*.class
    • com.borland.datastore.jdbc.*
    • com.borland.datastore.q2.*
  • Si vous utilisez DataExpress et qu'une instance de DataStore ou de DataStoreConnection est définie dans la propriété StorageDataSet.store, excluez les classes suivantes :
    • com.borland.dx.memorystore.*
  • Si StorageDataSet est utilisé mais ni QueryDataSet, ni QueryProvider, ni StoredProcedureDataSet ni StoredProcedureProvider, excluez les classes suivantes :
    • com.borland.dx.sql.*
  • Si DataExpress n'utilise pas de composant visuel à partir des bibliothèques JBCL ou dbSwing, excluez les classes suivantes :
    • com.borland.dx.text.*
  • Si com.borland.dx.dataset.TextDataFile n'est pas utilisé, excluez les classes suivantes :
    • com.borland.jb.io.*
    • com.borland.dx.dataset.TextDataFile.class
    • com.borland.dx.dataset.SchemaFile.class

Colonnes à incrémentation automatique

Vous pouvez spécifier des colonnes de type int et long comme ayant des valeurs AutoIncrement.

Les caractéristiques suivantes s'appliquent à toutes les valeurs des colonnes AutoIncrement :

  • Elles sont toujours uniques
  • Elles ne peuvent jamais avoir la valeur Null
  • Les valeurs des lignes supprimées ne peuvent jamais être réutilisées

Grâce à ces caractéristiques, les colonnes AutoIncrement sont idéales pour constituer des clés primaires à une seule colonne integer/long.

Une colonne AutoIncrement constituant l'identificateur interne d'une ligne, elle fournit l'accès aléatoire le plus rapide à une ligne particulière d'une table Blackfish SQL.

Chaque table ne peut avoir qu'une colonne AutoIncrement.  L'utilisation d'une colonne AutoIncrement économise dans votre table la place d'une colonne d'entiers et d'une colonne d'index secondaires si vous l'utilisez en remplacement d'une clé primaire. L'optimiseur de requêtes de Blackfish SQL optimise les requêtes faisant référence à une colonne AutoIncrement dans une clause WHERE. Pour avoir des instructions sur l'utilisation des colonnes AutoIncrement avec SQL, reportez-vous à "Utilisation des colonnes incrémentées automatiquement avec SQL" dans Référence SQL.

Colonnes à incrémentation automatique utilisant des JavaBeans DataExpress avec Blackfish SQL pour Java

Si vous utilisez DataExpress, pour créer une table avec une colonne AutoIncrement, donnez à la propriété Column.AutoIncrement la valeur true avant d'ouvrir la table. Si vous modifiez une table existante, vous devrez appeler la méthode StorageDataSet.restructure().

Composants compagnons de Blackfish SQL

La bibliothèque des composants dbSwing propose deux composants (sur la page des dbSwing supplémentaires de la palette des composants) facilitant la production d'applications Blackfish SQL solides.

  • DBDisposeMonitor dispose automatiquement des ressources des composants orientés données lorsqu'un conteneur est fermé. Elle comprend une propriété closeDataStores. Si sa valeur est true (valeur par défaut), elle ferme automatiquement toutes les bases de données Blackfish SQL liées aux composants nettoyés. Si vous mettez, par exemple, un DBDisposeMonitor dans un JFrame contenant des composants dbSwing liés à une base de données Blackfish SQL, quand vous fermez ce JFrame, DBDisposeMonitor ferme automatiquement la base de données Blackfish SQL. Ce composant est particulièrement utile pendant la construction d'applications simples à expérimenter avec Blackfish SQL.
  • DBExceptionHandler comprend un bouton Quitter. Il peut être caché via une valeur de propriété, mais il est visible par défaut. Un clic sur ce bouton ferme automatiquement tous les fichiers de base de données Blackfish SQL trouvés ouverts. DBExceptionHandler représente la boîte de dialogue par défaut affichée par les composants dbSwing quand une exception survient.

Utilisation des modules de données avec Blackfish SQL pour Java pour des composants JavaBeans DataExpress

Lors de l'utilisation d'une table Blackfish SQL avec un StorageDataSet, il est vraiment recommandé qu'ils soient tous regroupés à l'intérieur de modules de données. Effectuez toutes les références à ces StorageDataSet via les méthodes d'accès DataModule telles que businessModule.getCustomer. La raison en est que beaucoup de fonctionnalités exposées via les StorageDataSet le sont par les paramètres de propriété et d'événement.

Bien que la plupart des propriétés structurelles importantes du StorageDataSet persistent dans la table Blackfish SQL elle-même, ce n'est pas le cas des classes qui implémentent les interfaces écouteur d'événement. L'instanciation du StorageDataSet avec tous les paramètres, contraintes, champs calculés et filtres (implémentés avec les événements) de l'écouteur d'événement, assure il soit correctement maintenu à l'exécution comme à la conception.

Voir aussi

Autres langues