Utilización de un índice compuesto

El índice compuesto HashIndex mejora el rendimiento de la consulta y evita la costosa exploración de correlaciones. La característica también proporciona un método práctico para que la API HashIndex encuentre los objetos almacenados en memoria caché cuando los criterios de búsqueda implican muchos atributos.

Rendimiento mejorado

Un HashIndex compuesto proporciona una forma rápida y práctica para buscar objetos almacenados en memoria caché con varios atributos en los criterios de búsqueda de coincidencia. El índice compuesto soporta búsquedas completas de coincidencia de atributo, pero no soporta las búsquedas de rango.

Nota: Los índices compuestos no soportan el operador BETWEEN en el lenguaje de consulta de ObjectGrid porque BETWEEN requeriría el soporte de rango. Los condicionales mayor que (>) y menor que (<) tampoco funcionan porque requieren los índices de rango.

Un índice compuesto puede mejorar el rendimiento de las consultas si el índice compuesto apropiado está disponible para la condición WHERE. Esto significa que el índice compuesto tiene exactamente los mismos atributos que los implicados en la condición WHERE con todos los atributos coincidentes.

Una consulta podría tener muchos atributos implicados en una condición como en el ejemplo siguiente.

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

El índice compuesto puede mejorar el rendimiento de la consulta al evitar tener que explorar la correlación o unir diversos resultados de índice de un único atributo. En el ejemplo, si un índice compuesto se define con atributos (city,state,zipcode), el motor de consultas puede utilizar el índice compuesto para encontrar la entrada con city='Rochester', state='MN' y zipcode='55901'. Sin un índice compuesto y un índice de atributo en los atributos city, state y zipcode, el motor de consultas tendrá que explorar la correlación o unir varias búsquedas de atributo único, que normalmente tienen una sobrecarga costosa. Además, la consulta del índice compuesto sólo soporta un patrón de coincidencia completa.

Configuración de un índice compuesto

Puede configurar índices compuestos de tres formas: mediante XML, mediante programación o con anotaciones de entidad solo para correlaciones de entidad.

Configuración mediante programa

El código de ejemplo programático siguiente creará el mismo índice compuesto que el XML anterior.

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

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

Observe que la configuración de un índice compuesto es igual que la configuración de un índice ordinario con XML excepto por el valor de la propiedad attributeName. En el caso de un índice compuesto, el valor de attributeName es una lista de atributos delimitada por comas. Por ejemplo, la clase de valor Address tiene 3 atributos: city, state y zipcode. Un índice compuesto se puede definir con el valor de propiedad attributeName como "city,state,zipcode" que indica que city, state y zipcode se incluyen en el índice compuesto.

Además, tenga en cuenta que los HashIndexes compuestos no soportan las búsquedas de rango y, por lo tanto, no pueden tener la propiedad RangeIndex establecida en true.

Mediante XML

Para poder configurar un índice compuesto con XML, incluya código como, por ejemplo, el que aparece abajo en el elemento backingMapPluginCollections del archivo de configuración.

Índice compuesto - Configuración mediante 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>

Con anotaciones de entidad

En el caso de correlaciones de entidad, el acercamiento de anotaciones puede utilizarse para definir un índice compuesto. Puede definir una lista de CompositeIndex dentro de una anotación CompositeIndexes en el nivel de clase de la entidad. El índice CompositeIndex tiene un nombre y una propiedad attributeNames. Cada índice CompositeIndex está asociado con una instancia HashIndex aplicada al elemento BackingMap asociado de la entidad. El índice HashIndex está configurado como un índice de no intervalo.

@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 propiedad name de cada índice compuesto debe ser exclusivo dentro de la entidad y BackingMap. Si no se especifica el nombre, se utilizará un nombre generado. La propiedad attributeNames se utiliza para rellenar la propiedad attributeName de HashIndex con la lista de atributos delimitada por comas. Los nombres de atributo coinciden con los nombres de campos persistentes, cuando las entidades se configuran para utilizar el acceso a campo, o el nombre de la propiedad se haya definido para los convenios de denominación de JavaBeans para las entidades de acceso a propiedades. Por ejemplo: si el nombre de atributo es "street", el método getter de la propiedad es getStreet.

Búsquedas en índices compuestos

Después de configurar un índice compuesto, una aplicación puede utilizar el método findAll(Object) de la interfaz MapIndex para realizar búsquedas, como en el ejemplo siguiente.

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);// Cierre la sesión (opcional en la versión 7.1.1 y posterior) para un mejor rendimiento
sess.close();   

MapIndex.EMPTY_VALUE se asigna a compositeValue[ 0 ] que indica que el atributo city se excluye de la evaluación. Sólo los objetos con el atributo state igual a "MN" y el atributo zipcode igual a "55901" se incluirán en el resultado.

Las siguientes consultas se benefician de la configuración del índice compuesto anterior:

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'

El motor de consultas encontrará el índice compuesto apropiado y lo utiliza para mejorar el rendimiento de la consulta en casos de coincidencia de atributos total.

En algunos escenarios, la aplicación podría definir varios índices compuestos con atributos solapados para satisfacer todas las consultas con coincidencia total de los atributos. Un inconveniente de aumentar el número de índices es la posible sobrecarga de rendimiento en las operaciones de correlaciones.

Migración e interoperatividad

La única restricción del uso de un índice compuesto es que una aplicación no puede configurarlo en un entorno distribuido con contenedores heterogéneos. Los contenedores antiguos y nuevos no pueden mezclare, ya que los contenedores más antiguos no reconocerán una configuración de índice compuesto. El índice compuesto es como el índice de atributos ordinario existente, sólo que el primero permite la creación de índices sobre varios atributos. Si utiliza el índice de atributos ordinario, el uso del entorno de contenedores mixto es viable.