Verificación de salto de partición de range

Tenemos una gran cantidad de datos particionados en el valor del año utilizando la partición de range en Oracle. Hemos utilizado la partición de range, pero cada partición contiene datos solo durante un año. Cuando escribimos una consulta que apunta a un año específico, Oracle obtiene la información de esa partición pero aún así verifica si el año es el que hemos especificado. Como este año la columna no forma parte del índice, extrae el año de la tabla y lo compara. Hemos visto que cada vez que la consulta va a search datos de la tabla se está volviendo demasiado lenta.

¿Podemos de alguna manera evitar el oracle al comparar los valores del año ya que estamos seguros de que la partición contiene información por solo un año?

Actualizar:

  1. El tipo de datos de año en que se realiza la partición es de tipo número.

  2. No estamos seleccionando ninguna columna adicional. Solo estoy realizando un count(*) y no se están seleccionando columnas.

  3. Si eliminamos la condición y destinamos la consulta a una partición específica como select count(*) from table_name partition(part_2004) , es más rápida mientras select count(*) from table where year = 2004 es mucho más lenta.

  4. La partición está en la columna del año, que es un número y se realiza a continuación.

    año less que 2005 part_2004

    año less que 2006 part_2005

    año less que 2007 part_2006

…pronto

Sin el plan de explicación o la definición de la tabla, es realmente difícil saber qué sucede. Mi primera suposition es que tiene índices particionados LOCALES sin la columna del year . Ayudan con el COUNT (*) en una partición, sin embargo, parece que no se utilizan cuando consulta un solo año (al less en 10.2.0.3).

Aquí hay un pequeño ejemplo que reproduce su hallazgo (y una solución alternativa):

 SQL> CREATE TABLE DATA ( 2 YEAR NUMBER NOT NULL, 3 ID NUMBER NOT NULL, 4 extra CHAR(1000) 5 ) PARTITION BY RANGE (YEAR) ( 6 PARTITION part1 VALUES LESS THAN (2010), 7 PARTITION part2 VALUES LESS THAN (2011) 8 ); Table created SQL> CREATE INDEX ix_id ON DATA (ID) LOCAL; Index created SQL> INSERT INTO DATA 2 (SELECT 2009+MOD(ROWNUM, 2), ROWNUM, 'A' FROM DUAL CONNECT BY LEVEL <=1e4); 10000 rows inserted SQL> EXEC dbms_stats.gather_table_stats(USER, 'DATA', CASCADE=>TRUE); PL/SQL procedure successfully completed 

Ahora compare los dos planes de explicación:

 SQL> SELECT COUNT(*) FROM DATA WHERE YEAR=2010; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=197 Card=1 Bytes=4) 1 0 SORT (AGGREGATE) 2 1 PARTITION RANGE (SINGLE) (Cost=197 Card=5000 Bytes=20000) 3 2 TABLE ACCESS (FULL) OF 'DATA' (TABLE) (Cost=197 Card=5000...) SQL> SELECT COUNT(*) FROM DATA PARTITION (part1); Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=11 Card=1) 1 0 SORT (AGGREGATE) 2 1 PARTITION RANGE (SINGLE) (Cost=11 Card=5000) 3 2 INDEX (FULL SCAN) OF 'IX_ID' (INDEX) (Cost=11 Card=5000) 

Como puede ver, el índice no se usa cuando consulta el año directamente. Cuando agrega el año al índice LOCAL, se usará. Usé la instrucción COMPRESS 1 para decirle a Oracle que comprima la primera columna. El índice resultante es casi del mismo tamaño que el índice original (gracias a la compression) por lo que el performance no debería verse afectado.

 SQL> DROP INDEX ix_id; Index dropped SQL> CREATE INDEX ix_id ON DATA (year, ID) LOCAL COMPRESS 1; Index created SQL> SELECT COUNT(*) FROM DATA WHERE YEAR=2010; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=12 Card=1 Bytes=4) 1 0 SORT (AGGREGATE) 2 1 PARTITION RANGE (SINGLE) (Cost=12 Card=5000 Bytes=20000) 3 2 INDEX (RANGE SCAN) OF 'IX_ID' (INDEX) (Cost=12 Card=5000...) 

¿Estás seguro de que va a la table solo para verificar el año? Tal vez hay otras columnas involucradas?

¿Se suponía que la consulta solo funcionaba en índices (particionados)?

Si necesita ir a la table de todos modos, esa comprobación adicional no cuesta mucho (si la partición es correcta).

¿Puedes publicar la consulta y el plan de ejecución?