2012-05-04 9 views
9

que tenía una mesa Bla (float latitud, longitud de flotación, fecha CREATE_TIME, int OWNER_ID, .....)índice compuesto de Oracle para condiciones de consulta de rango

y mi código hace solamente una sola consulta

select * 
from Blah 
where latitude < l1 and latitude > l2 
and longitude < ll1 and longitude > ll2 
and create_time < t1 and create_time > t2 
and owner_id < o1 and owner_id > o2 ; 

(por supuesto, la L1 valores, L2, .... O1, O2 son params dinámicas procedentes de programa)

mi pregunta es qué tipo de índice que debería crear; ¿índice compuesto? en caso de índice compuesto, ¿qué columna debo poner primero? ¿qué tan efectivo es el índice?

Pensé en esto durante mucho tiempo y no pude encontrar documentos detallados sobre cómo funciona el índice de Oracle.

Puedo encontrar documentos que se implementan usando B-tree, en nuestro caso: cada tecla en el B-tree es una 4-tupla: (columna1, columna2, columna3, columna4) donde la relación de ordenamiento de tales tuplas es definido para ser orden léxico

para la consulta anterior, asumiendo que nuestro pedido es (owner_id, create_time, latitude, longitude), supongo que oracle primero necesitaría la búsqueda binaria hasta el punto (o1, t1, l1, ll1), para esta operación , el índice es de hecho útil. pero luego, tenemos que encontrar el punto final de este primer interio: necesitamos encontrar (o1, t1, l1, ll2), esto también se puede hacer mediante búsqueda binaria.

lado, tenemos que encontrar la siguiente sección que satisfaga la condición, por lo que tenemos que find (o1, t1, lx, LL1), donde lx es el siguiente valor más grande que l1, no pudimos encontrar esto mediante la búsqueda binaria también. pero en nuestro caso, es muy probable que, para la misma latitud, no haya más de 1 longitud, , por lo que la búsqueda binaria aquí no es más efectiva que la exploración lineal.

siguiendo este espíritu, parece que debemos poner primero la columna con una cardinalidad de rango de valor pequeño, en este caso, create_time, si nuestros puntos se crean en solo unos pocos días. también, si nunca hacemos condiciones de rango, pero solo equivale a (=) condiciones, entonces no importa qué columna es la primera, ¿verdad?

para hacerlo más claro, aquí es un ejemplo más simple:

digamos que tengo 2 columnas, X, Y y

en el PP, los valores para ambos son [1,2, ... 0,100], por lo que tenemos 100x100 filas

mi consulta es

select * from mytable where X > 34 and X < 78 and Y > 12 and Y < 15; 

dicen que nuestro índice está en (X, Y), por lo que la regla de comparación entre los 2 valores son

v1 < v2 <=====> v1.x < v2.x || v1.x == v2.x && v1.y < v2.y 

dada la regla de ordenación anterior, podemos ver que los valores en el índice son dispuestos en serie como el (los valores de x, y):

1,1, 1,2 1,3 .... 1,100  
2,1 2,2 2,3 ......2,100 
..... 
100,1 100,2 ....... 100,100 

ahora, para buscar los valores de la consulta, el recorrido del árbol B necesita localizar (78-34-1) intervalos, de ahí (78-34-1) * 2 búsqueda (1 para el comienzo uno para las ubicaciones finales), no solo 2 búsquedas.

por lo que si tenemos dimensiones superiores, el intervalo que cuenta aumenta exponencialmente con el número de dimensiones, por lo que la indexación puede no ser útil más ------ esta es mi preocupación

muchas gracias Yang

Respuesta

9

Si su único objetivo es crear un índice para optimizar esta consulta, preferiría que las columnas en el índice compuesto se ordenaran primero con la columna más selectiva. Si los predicados en latitude eliminan sustancialmente más filas que los otros predicados, será más eficiente tener esa columna primero. Si los predicados en owner_id eliminan sustancialmente más filas que los otros predicados, será más eficiente tener esa columna primero.

En realidad, sin embargo, raramente estamos creando índices cuyo único propósito es optimizar una sola consulta. En general, para que la sobrecarga del mantenimiento del índice valga la pena, queremos que nuestros índices sean útiles en muchas consultas. En el caso de un índice compuesto, eso significa ordenar las columnas por la probabilidad de que una consulta tenga predicados en esa columna. Si tiene un índice compuesto en owner_id, create_time, latitude, longitude, por ejemplo, puede usarlo para consultas que simplemente especifiquen predicados en owner_id. Pero no utilizaría, de manera realista, ese índice para consultas que simplemente especifiquen predicados en longitude.

3

Primero, tenga en cuenta que la "B" en "B-Tree" no es "binaria".

En segundo lugar, cuando se trata de la indexación en Oracle también tiene la opción de un índice de mapa de bits si:

  1. Usted tiene una licencia de Enterprise Edition
  2. Usted no tiene muchas sesiones que modifican simultáneamente la tabla
  3. Sus valores indexados no están cerca de ser únicos (declaraciones que los índices de mapa de bits sólo se pueden usar para las columnas cardinalidad bajas son generalmente exagerada)

Uno tipo de consulta en la que los índices de mapas de bits se destacan es en la combinación eficiente de predicados en múltiples columnas, especialmente donde el conjunto de columnas predicadas varía (lo que puede no ser el caso para usted, por supuesto). Si cumple con las tres condiciones anteriores, valdría la pena probar el efecto de tener cuatro índices de mapa de bits separados sobre la mesa.

+0

gracias, pero ahora solo me preocupa el problema del índice B-tree; aunque en la práctica Oracle bien puede usar el índice de mapa de bits, como usted señaló –

0

¿Esta tabla se usa para OLTP o como DWH? si no tiene muchos enunciados DML de fila única/multiproceso en esta tabla, puede usar índices de mapa de bits. índices de mapa de bits le permite ROWID AND operadores entre múltiples índices (transformación estrella Aka). para hacerlo, crea un índice de mapa de bits en cada columna. Como he dicho, esta solución se adapta mejor al sistema DWH donde tiene una sola inserción de lote.

0

Las consultas de rango multidimensional se manejan mejor, en mi humilde opinión, fuera de los índices de árbol B estándar. Se pueden encontrar algunos documentos sobre el tema general mediante una búsqueda en la web sobre "consultas de rango multidimensional".

Oracle proporciona un producto llamado Oracle Spatial. La documentación de este producto incluye, en Chapter 4, ejemplos y explicaciones sobre la creación de índices espaciales y la realización de consultas. No hay nueva sintaxis SQL; su ejemplo para la creación de índices es:

CREATE INDEX territory_idx ON territories (territory_geom) 
    INDEXTYPE IS MDSYS.SPATIAL_INDEX; 

que crea un índice de árbol R.

Creo que la existencia de R-trees, kdb-trees y estructuras espaciales similares es evidencia del hecho de que los B-trees estándar probablemente no son muy adecuados para este tipo de aplicaciones.

1

Una solución simple de fuerza bruta es crear múltiples combinaciones de índices en la misma tabla, ejecutar la consulta con EXPLAIN PLAN activada y luego elegir el índice que su DBMS prefiera usar.

Cuestiones relacionadas