sql >> Base de Datos >  >> RDS >> Oracle

Índice Oracle 11 solo para una parte de los datos

Permítanme primero asegurarme de que entiendo la pregunta correctamente:

  • Desea acelerar SELECT .. WHERE C_D IS NULL pero tú no desea acelerar cualquiera de las consultas que buscan un C_D que no sea NULL.
  • También desea asegurarse de que no haya valores no NULL "innecesarios" en el índice, para ahorrar espacio.

Si ese entendimiento es correcto, entonces lo que necesita es un funcional índice. Es decir. un índice en una función en un campo, no un campo en sí...

CREATE INDEX T_IE1 ON T (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) COMPRESS

...que luego consultaría como...

SELECT * FROM T WHERE (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1

...que es equivalente a...

SELECT * FROM T WHERE C_D IS NULL

...pero más rápido ya que usa el índice:

Esto ahorra espacio porque los índices de una sola columna no almacenan valores NULL. Además, use COMPRESS ya que el índice solo contendrá una clave, por lo que no hay necesidad de desperdiciar espacio repitiendo la misma clave una y otra vez en la estructura del índice.

NOTA:En Oracle 11, también puede crear una columna virtual basada en funciones (basado en el CASE expresión anterior), luego indexe y consulte en esa columna directamente, para ahorrar algo de tipeo repetitivo.

--- EDITAR ---

Si también está interesado en consultar sobre C_I junto con C_D IS NULL , podrías...

CREATE UNIQUE INDEX T_IE2 ON T (C_I, CASE WHEN C_D IS NULL THEN 1 ELSE NULL END)

...y consultarlo con (por ejemplo)...

SELECT * FROM T WHERE C_I > 'some value' AND (CASE WHEN C_D IS NULL THEN 1 ELSE NULL END) = 1

...que es equivalente a...

SELECT * FROM T WHERE C_I > 'some value' AND C_D IS NULL

...pero más rápido, ya que usa el índice T_IE2 .

De hecho, este es el único índice que necesita en su tabla ("cubre" la clave principal, por lo que ya no necesita un índice separado solo en C_I). Lo que también significa que los mismos ROWID nunca se almacenan en más de un índice, lo que ahorra espacio.

NOTA:COMPRESS ya no tiene sentido para el índice T_IE2 .

--- EDICIÓN 2 ---

Si le importa más la simplicidad que el espacio, puede crear un índice compuesto en {C_I, C_D}. Oracle almacena valores NULL en índice compuesto siempre que haya al menos un valor no NULL en la misma tupla:

CREATE UNIQUE INDEX T_IE3 ON T (C_I, C_D)

Esto usa el índice:

SELECT * FROM T WHERE C_I > 1 AND C_D IS NULL

Como en la EDICIÓN anterior, este es el único índice que necesita en su tabla.