Utilisation d'un index composite

L'index HashIndex composite permet d'améliorer les performances des requêtes et d'éviter des recherches dans les mappes, consommatrices en ressources. Il facilite également les recherches d'objets mis en cache effectuées par l'API HashIndex lorsque les critères de recherche contiennent plusieurs attributs.

Amélioration des performances

L'index HashIndex de hachage constitue un outil rapide et pratique pour rechercher des objets mis en cache lorsque plusieurs attributs sont indiqués dans les critères de recherche. Il prend en charge les recherches de correspondance d'attribut complète, mais pas les recherches de plages.

Remarque : Les index composites ne prennent pas en charge l'opérateur BETWEEN dans le langage de requête ObjectGrid car la prise en charge des plages est obligatoire pour cet opérateur. De même, les opérateurs conditionnels "supérieur à" (>) et "inférieur à" (<) ne fonctionnent pas, pour la même raison.

L'index composite permet d'améliorer les performances des requêtes lorsque l'index composite approprié est disponible pour la condition WHERE. Ses attributs sont alors exactement les mêmes que ceux indiqués dans la condition WHERE lorsque les attributs correspondent complètement.

Une requête, peut contenir plusieurs attributs au sein d'une même condition, comme dans l'exemple ci-dessous :

SELECT a FROM Address a WHERE a.city='Rochester' AND a.state='MN' AND a.zipcode='55901'

L'index composite améliore les performances des requêtes car il permet d'éviter les recherches dans les mappes ou de joindre plusieurs résultats d'index contenant un seul attribut. Dans cet exemple, si un index composite est défini avec des attributs (city,state,zipcode), le moteur de recherche peut utiliser l'index composite pour rechercher l'entrée associée à city='Rochester', state='MN' et zipcode='55901'. Sans l'index composite et l'index d'attribut pour les attributs city, state et zipcode, le moteur de recherche doit effectuer la recherche dans la mappe ou joindre plusieurs recherches contenant un seul attribut, ce qui entraîne généralement une augmentation de la consommation des ressources. Par ailleurs, l'exécution d'une requête pour l'index composite prend uniquement en charge le modèle de correspondance complète.

Configuration d'un index composite

Vous pouvez configurer une indexation composite de trois manières différentes : avec XML, à l'aide d'un programme, et avec des annotations d'entité uniquement pour les mappes d'entités.

Configuration par programmation

Les lignes de code représentées ci-dessous permettent de créer le même index composite que dans l'exemple précédent.

	  HashIndex mapIndex = new HashIndex();
    mapIndex.setName("Address.CityStateZip");
    mapIndex.setAttributeName(("city,state,zipcode"));
    mapIndex.setRangeIndex(true);

    BackingMap bm = objectGrid.defineMap("mymap");
    bm.addMapIndexPlugin(mapIndex);

Notez que la configuration d'un index composite est identique à la configuration d'un index standard avec XML, à l'exception de la valeur de la propriété attributeName. Dans un index composite, cette valeur est une liste d'attributs séparés par des virgules. Par exemple, la classe de valeur Address a trois attributs : city, state et zipcode. Un index composite peut être défini avec la valeur de propriété attributeName "city,state,zipcode" indiquant que la ville, l'état et le code postal sont inclus dans l'index composite.

Notez également qu'un index HashIndexes composite ne prend pas en charge les recherches de plages et que sa propriété RangeIndex ne peut pas être associée à true.

Utilisation de XML

Pour configurer un index composite avec XML, entrez des lignes de code semblables à ce qui suit dans l'élément backingMapPluginCollections du fichier de configuration.

Index composite - configuration de type XML
<bean id="MapIndexPlugin"  className="com.ibm.websphere.objectgrid.plugins.index.HashIndex">
<property name="Name" type="java.lang.String" value="Address.CityStateZip"/>
<property name="AttributeName" type="java.lang.String" value="city,state,zipcode"/>
</bean>

Avec annotations d'entités

Dans le cas d'une mappe d'entités, il est possible d'utiliser des annotations pour définir un index composite. Vous pouvez définir une liste de CompositeIndex dans l'annotation CompositeIndexes au niveau de la classe d'entités. Le CompositeIndex a un nom et une propriété attributeNames. Chaque CompositeIndex est associé à une instance HashIndex appliquée à la mappe de sauvegarde associée de l'entité. L'index HashIndex est configuré en tant qu'index ne contenant pas de plage.

@Entity
@CompositeIndexes({
    @CompositeIndex(name="CityStateZip", attributeNames="city,state,zipcode"), 
    @CompositeIndex(name="lastnameBirthday", attributeNames="lastname,birthday")
 })
public class Address {
    @Id int id;
    String street;
    String city;
    String state;
    String zipcode;
    String lastname;
    Date birthday;
}

La propriété de nom de chaque index composite doit être unique dans l'entité et dans la mappe de sauvegarde. Si aucun nom n'est indiqué, un nom est généré. La propriété attributeNames permet de remplir le nom d'attribut HashIndex avec la liste d'attributs séparés par des virgules. Les noms d'attribut coïncident avec les noms de zone persistante lorsque les entités sont configurées pour utiliser l'accès par zone, ou le nom de propriété tel qu'il est défini pour les conventions de dénomination JavaBeans pour les entités d'accès par propriété. Par exemple : si le nom d'attribut est "street", la méthode d'accès get de la propriété se nommera getStreet.

Execution de recherches avec un index composite

Une fois l'index composite configuré, l'application peut utiliser la méthode findAll(Object) de l'interface MapIndex pour exécuter des recherches, comme ci-dessous.

Session sess = objectgrid.getSession();
ObjectMap map = sess.getMap("MAP_NAME");
MapIndex codeIndex = (MapIndex) map.getIndex("INDEX_NAME");
Object[] compositeValue = new Object[]{ MapIndex.EMPTY_VALUE,
			"MN", "55901"};
Iterator iter = mapIndex.findAll(compositeValue);
// Fermer la session (facultatif dans les versions 7.1.1 et ultérieures) pour améliorer les performances
sess.close();   

La valeur MapIndex.EMPTY_VALUE est affectée à compositeValue[ 0 ] qui indique que l'attribut city est exclu de l'évaluation. Seuls les objets dont l'attribut state est égal à "MN" et l'attribut zipcode est égal à "55901" figureront dans le résultat.

Les requêtes suivantes bénéficient de la configuration de l'index composite précédent :

SELECT a FROM Address a WHERE a.city='Rochester' AND a.state='MN' AND a.zipcode='55901'

SELECT a FROM Address a WHERE a.state='MN' AND a.zipcode='55901'

Le moteur de requête cherche l'index composite approprié et l'utilise pour améliorer les performances des requêtes dans les recherches à correspondance complète.

Dans certains scénarios, l'application peut avoir besoin de définir plusieurs index composites dont les attributs se chevauchent pour satisfaire toutes les requêtes à correspondance complète. L'augmentation du nombre d'index risque de ralentir les performances des opérations relatives aux mappes.

Migration et interopérabilité

La seule contrainte liée à l'utilisation d'un index composite est qu'une application ne peut pas le configurer dans un environnement réparti contenant des conteneurs hétérogènes. Il est impossible de faire cohabiter des conteneurs anciens et nouveaux, car les anciens ne reconnaissent pas la configuration d'index composite. Celui-ci est semblable à un index d'attribut normal, mais il permet en outre l'indexation de plusieurs attributs. En cas d'utilisation d'un index d'attribut standard, un environnement composé de plusieurs types de conteneur est viable.