Plan de consulta

Todas las consultas de eXtreme Scale tienen un plan de consulta. El plan describe cómo el motor de consulta interactúa con ObjectMaps e índices. Consulte el plan de consulta para determinar si los índices o serie de consulta se están utilizando correctamente. El plan de consulta también se puede utilizar para explorar las diferencias que pequeños cambios en una serie de consulta realizan en la forma en la que eXtreme Scale ejecuta una consulta.

El plan de consulta puede verse de dos modos:

Método getPlan

El método getPlan en las interfaces ObjectQuery y Query devuelve una serie que describe el plan de consulta. Esta serie puede verse en una salida estándar o en un archivo de anotaciones cronológicas.
Nota: En un entorno distribuido, el método getPlan no se ejecuta en el servidor y no refleja los índices definidos. Para ver el plan, utilice un agente para visualizar el plan en el servidor.

Rastreo del plan de consulta

El plan de consulta puede verse mediante el rastreo de ObjectGrid. Para habilitar el rastreo del plan de consulta, utilice la especificación de rastreo siguiente:

QueryEnginePlan=debug=enabled

Consulte el apartado Recopilación de rastreo para obtener más información sobre cómo habilitar el rastreo y buscar los archivos de anotaciones cronológicas de rastreo.

Ejemplos de plan de consulta

El plan de consulta utiliza la palabra para indicar que la consulta itera por una colección de ObjectMap o por una colección derivada como por ejemplo: q2.getEmps(), q2.dept o una colección temporal devuelta por el bucle interno. Si la colección es de un ObjectMap, el plan de consulta muestras si se utiliza una exploración secuencial (indicada mediante INDEX SCAN), un índice exclusivo o un índice no exclusivo. El plan de consulta utiliza una serie de filtro para listar las expresiones de condición que se aplican a una colección.

En una consulta de objeto no se suele utilizar un producto cartesiano. La consulta siguiente explora toda la correlación EmpBean en el bucle externo y explora toda la correlación DeptBean en el bucle interno:

SELECT e, d FROM EmpBean e, DeptBean d

Rastreo de plan:

for q2 in EmpBean ObjectMap using INDEX SCAN
     for q3 in DeptBean ObjectMap using INDEX SCAN
   returning new Tuple( q2,  q3  )

La consulta siguiente recupera todos los nombres de los empleados de un departamento determinado; para ello, explora secuencialmente la correlación EmpBean para obtener un objeto employee. En el objeto employee, la consulta navega a su objeto department y aplica el filtro d.no=1. En este ejemplo, cada empleado tiene solo una referencia de objeto de departamento, así que el bucle interno se ejecuta una sola vez:

SELECT e.name FROM EmpBean e JOIN e.dept d WHERE d.no=1

Rastreo de plan:

for q2 in EmpBean ObjectMap using INDEX SCAN
     for q3 in  q2.dept
      filter ( q3.getNo() = 1 )
   returning new Tuple( q2.name  )

La consulta siguiente equivale a la anterior. Sin embargo, la consulta siguiente tiene un mejor rendimiento porque en primer lugar acota el resultado a un solo objeto de departamento utilizando el índice exclusivo definido sobre el número de campo de clave primaria DeptBean. A partir del objeto department, la consulta navega hasta los objetos employee para obtener sus nombres:

SELECT e.name FROM DeptBean d JOIN d.emps e WHERE d.no=1

Rastreo de plan:

for q2 in DeptBean ObjectMap using UNIQUE INDEX key=(1)
     for q3 in  q2.getEmps()
   returning new Tuple( q3.name  )

La consulta siguiente busca todos los empleados que trabajan en desarrollo o ventas. La consulta explora toda la correlación EmpBean y realiza un filtrado adicional al evaluar las expresiones: d.name = 'Sales' o d.name='Dev'

SELECT e FROM EmpBean e, in (e.dept) d WHERE d.name = 'Sales' 
	or d.name='Dev'

Rastreo de plan:

for q2 in EmpBean ObjectMap using INDEX SCAN
     for q3 in  q2.dept
      filter (( q3.getName() = Sales ) OR ( q3.getName() = Dev ) )
   returning new Tuple( q2  )

La consulta siguiente equivale a la anterior, pero esta consulta ejecuta un plan de consulta diferente y utiliza un índice de intervalo en el nombre de campo. En general, esta consulta tiene un mejor rendimiento porque el índice del campo de nombre se utiliza para limitar los objetos department, que se ejecuta rápidamente si sólo unos pocos departamentos son de desarrollo o ventas.

SELECT e FROM DeptBean d, in(d.emps) e WHERE d.name='Dev' or d.name='Sales'

Rastreo de plan:

IteratorUnionIndex of
    
     for q2 in DeptBean ObjectMap using INDEX on name = (Dev)
       for q3 in  q2.getEmps()
    
    
     for q2 in DeptBean ObjectMap using INDEX on name = (Sales)
       for q3 in  q2.getEmps()

La consulta siguiente busca departamentos que no tienen ningún empleado:

SELECT d FROM DeptBean d WHERE NOT EXISTS(select e from d.emps e)

Rastreo de plan:

for q2 in DeptBean ObjectMap using INDEX SCAN
    filter ( NOT  EXISTS (    correlated collection defined as 
      
       for q3 in  q2.getEmps()
       returning new Tuple( q3      )
 
   returning new Tuple( q2  )

La consulta siguiente equivale a la anterior, pero utiliza la función escalar SIZE. Esta consulta tiene un rendimiento similar pero es más fácil de escribir.

SELECT d FROM DeptBean d WHERE SIZE(d.emps)=0
for q2 in DeptBean ObjectMap using INDEX SCAN
    filter (SIZE( q2.getEmps()) = 0 )
   returning new Tuple( q2  )

El ejemplo siguiente es otra manera de escribir la misma consulta que la anterior con un rendimiento similar, pero esta consulta es más fácil de escribir también:

SELECT d FROM DeptBean d WHERE d.emps is EMPTY

Rastreo de plan:

for q2 in DeptBean ObjectMap using INDEX SCAN
    filter ( q2.getEmps() IS EMPTY  )
   returning new Tuple( q2  )

La consulta siguiente busca empleados con un domicilio que coincida al menos con una de las direcciones del empleado cuyo nombre sea igual al valor del parámetro. El bucle interno no tiene dependencia del bucle externo. La consulta ejecuta el bucle interno una sola vez.

SELECT e FROM EmpBean e WHERE e.home =  any (SELECT e1.home FROM EmpBean e1 
	WHERE e1.name=?1)
for q2 in EmpBean ObjectMap using INDEX SCAN
    filter ( q2.home =ANY     temp collection defined as 
      
       for q3 in EmpBean ObjectMap using INDEX on name = ( ?1)
       returning new Tuple( q3.home      )
 )
   returning new Tuple( q2  )

La consulta siguiente es igual a la anterior, pero tiene una subconsulta correlacionada; además, el bucle interno se ejecuta repetidamente.

SELECT e FROM EmpBean e WHERE EXISTS(SELECT e1 FROM EmpBean e1 WHERE 
	e.home=e1.home and e1.name=?1)

Rastreo de plan:

for q2 in EmpBean ObjectMap using INDEX SCAN
    filter ( EXISTS (    correlated collection defined as 
      
       for q3 in EmpBean ObjectMap using INDEX on name = (?1)
        filter ( q2.home =  q3.home )
       returning new Tuple( q3      )

   returning new Tuple( q2  )