Ejemplo de reescritura de compilador: movimiento de operación
Durante la reescritura de consultas, el optimizador puede mover el punto en el que se realiza la operación DISTINCT, para reducir el coste de esta operación. En algunos casos, la operación DISTINCT se puede eliminar completamente.
select distinct empno, firstnme, lastname
from employeepodría reescribirse eliminando la cláusula DISTINCT: select empno, firstnme, lastname
from employeeEn este ejemplo, debido a que se está seleccionando la clave primaria, el compilador sabe que cada fila devuelta es exclusiva. En este caso, la palabra clave DISTINCT es redundante. Si la consulta no se reescribe, el optimizador debe crear un plan con el proceso necesario (por ejemplo, una clasificación) para asegurarse de que los valores de columna son exclusivos.
Ejemplo: desplazamiento descendente de predicado general
create view d11_employee
(empno, firstnme, lastname, phoneno, salary, bonus, comm) as
select empno, firstnme, lastname, phoneno, salary, bonus, comm
from employee
where workdept = 'D11' select firstnme, phoneno
from d11_employee
where lastname = 'BROWN'Durante la reescritura de la consulta, el compilador envía el predicado lastname = 'BROWN' a la vista D11_EMPLOYEE . Esto permite que el predicado se aplique antes y potencialmente de forma más eficiente. La consulta real que se podría ejecutar en este ejemplo es la siguiente: select firstnme, phoneno
from employee
where
lastname = 'BROWN' and
workdept = 'D11'El desplazamiento descendente de predicado no se limita a las vistas. Otras situaciones en las que los predicados se pueden desplazar hacia abajo son UNION, GROUP BY y tablas derivadas (expresiones de tabla anidadas o expresiones de tabla comunes).
Ejemplo-Decorrelación
select p.projno, e.empno, e.lastname, e.firstname,
e.salary+e.bonus+e.comm as compensation
from employee e, project p
where
p.empno = e.empno and
p.projname like '%PROGRAMMING%' and
e.salary+e.bonus+e.comm <
(select avg(e1.salary+e1.bonus+e1.comm)
from employee e1, project p1
where
p1.projname like '%PROGRAMMING%' and
p1.projno = p.projno and
e1.empno = p1.empno)Debido a que esta consulta está correlacionada y debido a que es poco probable que tanto PROJECT como EMPLOYEE se particionen en PROJNO, la difusión de cada proyecto en cada partición de base de datos es posible. Además, la subconsulta tendría que evaluarse muchas veces.
- Determine la lista distinta de empleados que trabajan en proyectos de programación y llámelo DIST_PROJS. Debe ser distinto para asegurarse de que la agregación se realiza sólo una vez para cada proyecto:
with dist_projs(projno, empno) as (select distinct projno, empno from project p1 where p1.projname like '%PROGRAMMING%') - Una DIST_PROJS con la tabla EMPLOYEE para obtener la remuneración promedio por proyecto, AVG_PER_PROJ:
avg_per_proj(projno, avg_comp) as (select p2.projno, avg(e1.salary+e1.bonus+e1.comm) from employee e1, dist_projs p2 where e1.empno = p2.empno group by p2.projno) - La consulta reescrita es:
select p.projno, e.empno, e.lastname, e.firstname, e.salary+e.bonus+e.comm as compensation from project p, employee e, avg_per_prog a where p.empno = e.empno and p.projname like '%PROGRAMMING%' and p.projno = a.projno and e.salary+e.bonus+e.comm < a.avg_comp
Esta consulta calcula el avg_comp por proyecto (avg_per_proj). A continuación, el resultado se puede difundir a todas las particiones de base de datos que contienen la tabla EMPLOYEE.