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:
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.
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 )