Guia del Programador de PostgreSQL | ||
---|---|---|
Anterior | Revisi�n de las caracter�sticas internas de PostgreSQL | Siguiente |
La tarea del planificador/optimizador es crear un plan de ejecuci�n �ptimo. Primero combina todas las posibles v�as de barrer (scannear) y cruzar (join) las relaciones que aparecen en una consulta. Todas las rutas creadas conducen al mismo resultado y es el trabajo del optimizador estimar el coste de ejecutar cada una de ellas para encontrar cual es la m�s econ�mica.
El planificador/optimizador decide qu� planes deber�an generarse bas�ndose en los tipos de �ndices definidos sobre las relaciones que aparecen en una consulta. Siempre existe la posibilidad de realizar un barrido secuencial de una relaci�n, de modo que siempre se crea un plan que s�lo utiliza barridos secuenciales. Se asume que hay definido un �ndice en una relaci�n (por ejemplo un �ndice B-tree) y una consulta contiene la restricci�n relation.attribute OPR constant. Si relation.attribute acierta a coincidir con la clave del �ndice B-tree y OPR es distinto de '<>' se crea un plan utilizando el �ndice B-tree para barrer la relaci�n. Si hay otros �ndices presentes y las restricciones de la consulta aciertan con una clave de un �ndice, se considerar�n otros planes.
Tras encontrar todos los planes utilizables para revisar relaciones �nicas, se crean los planes para cruzar (join) relaciones. El planificador/optimizador considera s�lo cruces entre cada dos relaciones para los cuales existe una cl�usula de cruce correspondiente (es decir, para las cuales existe una restricci�n como WHERE rel1.attr1=rel2.attr2) en la cualificaci�n de la WHERE. Se generan todos los posibles planes para cada cruce considerado por el planificador/optimizador. Las tes posibles estrategias son:
Cruce de iteraci�n anidada (nested iteration join): La relaci�n derecha se recorre para cada tupla encontrada en la relaci�n izquierda. Esta estrategia es f�cil de implementar pero puede consumir mucho tiempo.
Cruce de ordenaci�n mezclada (merge sort join): Cada relaci�n es ordenada por los atributos del cruce antes de iniciar el cruce mismo. Despu�s se mezclan las dos relaciones teniendo en cuenta que ambas relaciones est�n ordenadas pro los atributos del cruce. Este modelo de cruce es m�s atractivo porque cada relaci�n debe ser barrida s�lo una vez.
Cruce indexado (hash join): La relaci�n de la derecha se indexa primero sobre sus atributos para el cruce. A continuaci�n, se barre la relaci�n izquierda, y los valores apropiados de cada tupla encontrada se utilizan como clave indexada para localizar las tuplas de la relaci�n derecha.
Daremos ahora una peque�a descripci�n de los nodos que aparecen en el plan. La figura \ref{plan} muestra el plan producido para la consulta del ejemplo \ref{simple_select}.
El nodo superior del plan es un nodo Cruce Mezclado (MergeJoin) que tiene dos sucesores, uno unido al campo �rbol izquierdo (lefttree) y el segundo unido al campo �rbol derecho (righttree). Cada uno de los subnodos representa una relaci�n del cruce. Como se mencion� antes, un cruce de mezcla ordenada requiere que cada relaci�n sea ordenada. Por ello encontramos un nodo Sort en cada subplan. La cualificaci�n adicional dada en la consulta (s.sno > 2) se env�a tan lejos como es posible y se une al campo qpqual de la rama SeqScan del nodo del correspondiente subplan.
La lista unida al campo mergeclauses del nodo Cruce Mezclado (MergeJoin) contiene informaci�n sobre los atributos de cruce. Los valores 65000 y 65001 de los campos varno y los nodos VAR que aparecen en la lista mergeclauses (y tambi�n en la lista objetivo) muestran que las tuplas del nodo actual no deben ser consideradas, sino que se deben utilizar en su lugar las tuplas de los siguientes nodos "m�s profundos" (es decir, los nodos superiores de los subplanes).
N�tese que todos los nodos Sort y SeqScan que aparecen en la figura \ref{plan} han tomado una lista objetivo, pero debido a la falta de espacio s�lo se ha dibujado el correspondiente al Cruce Mezclado.
Otra tarea realizada por el planificador/optimizador es fijar los identificadores de operador en los nodos Expr y Oper. Como se mencion� anteriormente, Postgres soporta una variedad de tipos diferentes de datos, e incluso se pueden utilizar tipos definidos por el usuario. Para ser capaz de mantener la gran cantidad de funciones y operadores, es necesario almacenarlos en una tabla del sistema. Cada funci�n y operador toma un identificador de operador �nico. De acuerdo con los tipos de los atributos usados en las cualificaciones, etc, se utilizan los identificadores de operador apropiados.