2009-09-29 10 views
9

En el mundo de Oracle, tengo la impresión de que las vistas basadas en otros puntos de vista se consideran malas prácticas. Yo mismo me he quejado de esto cuando el intento de resolver problemas de rendimiento y el anidamiento parecía excesivo y oculté la complejidad innecesaria en las vistas subyacentes. Ahora me encuentro en la situación de pensar que puede no ser tan clara:¿Está BIEN anidar las vistas de la base de datos?

Tengo usuarios que muy específicamente necesitan que los números de contabilidad de una vista coincidan con los de otra que los procesa en mayor detalle. Si alguna vez cambian algo en uno, quieren que el otro lo refleje de inmediato, sin que nadie tenga que pensar en este requisito en unos pocos años e informes que muestren números que no coinciden mientras resuelven las cosas.

¿Está bien anidar vistas en este caso?

¿Cambia cosas si la vista interior contiene una vista más importante que contiene precios relevantes (es decir, se supone que "siempre" debe usar esta vista para determinar los precios)?

+0

+1, buena pregunta, muchas opiniones como pueden ver. Probablemente no sea una respuesta única para todos. – DCookie

Respuesta

6

El problema principal con las vistas de anidamiento es que es más probable que el optimizador de consultas se confunda y produzca un plan subóptimo. Aparte de esto, no hay una sobrecarga específica para usar vistas en vistas a menos que hagan algo a lo que el optimizador no pueda empujar predicados.

Esto significa que la mejor opción es probar las vistas anidadas. Vea si obtiene planes de consulta razonables fuera de los informes. Si causa problemas, entonces puede que tenga que volver a pensar su estrategia.

+3

+1, la mejor forma de responder a este tipo de preguntas es probarlo y medir el impacto en el rendimiento. Explicar Plan es tu amigo. – DCookie

1

Las mejores prácticas no siempre cubren todo. Creo que tienes una justificación clara para anidarlos, solo por esta vez.

0

También es bueno tener en cuenta que en el proceso de creación de consultas de bases de datos complejas, las vistas anidadas son lo mejor, por ejemplo, si necesita un operador matemático construido en 2 columnas, por ejemplo SUM (Col1, Col2) puede ser mejor anidar vistas para que la suma sea una columna en sí misma en lugar de tener que hacer algo como

"SELECCIONAR Total/SUM (Col1, Col2), SUM (Col1, Col2) * 2, Col1/SUM (Col1, Col2) ... "

Sin embargo, no estoy seguro de entender 100% - ¿Por qué se necesitan 2 vistas? ¿No pueden los dos usuarios mirar la vista 1 y derivar un procesamiento adicional en una vista de otra capa por encima de esa?

1

Estoy anidando vistas de 3 niveles de profundidad en Oracle 10g R2. El rendimiento parece correlacionarse con las declaraciones seleccionadas en las vistas, en lugar de con la profundidad de la vista. En particular, la cláusula "IN" parece estar causando muchos problemas.

+3

'in' es semánticamente equivalente a una serie de operadores 'o'. 'O' los predicados no son sargibles (un término de SQL Server que significa que un predicado se puede resolver usando un índice), aunque los optimizadores modernos están mejorando al traducirlos en algo que se puede resolver de esta manera. – ConcernedOfTunbridgeWells

3

Creo que se encuentra en la pendiente resbaladiza donde la reutilización del código y el rendimiento van a entrar en conflicto. Puedes probarlo y ver qué tan mal afectará el rendimiento. Aquí tenemos un par de bases de datos donde tienen vistas apiladas y francamente el rendimiento es miserable y ahora todos los involucrados deseaban no haberlo diseñado de esa manera.

+2

Como cualquier cosa, se puede abusar de ella. Lo realmente bueno de las vistas es que puede cambiar la implementación (consulta de la vista y la estructura de la tabla subyacente) sin afectar la interfaz. No seguiría ciegamente una política solo por el bien de la política. – David

0

Las mejores razones para utilizar una vista serían:

  1. prevenir la duplicación de la misma consulta.
  2. impedir el acceso directo a las tablas por otros escritores de consultas
  3. crear una capa de seguridad (similar a # 2).

Me doy cuenta que también puede ayudar a simplificar una consulta más compleja, pero se acostumbra. Puede encontrar que una función definida por el usuario (tabla) puede ser una mejor solución. De cualquier forma, el rendimiento tendrá éxito.

2

Siempre hay una compensación entre el tiempo de codificación, la facilidad o la calidad del código y el rendimiento.

Anidar vistas es muy fácil de codificar y, dadas las circunstancias correctas, facilita la lectura. También puede reducir el tiempo. Se puede decir que reduce la calidad y, a menudo, reduce el rendimiento ... ¿pero en qué medida?

Todo es subjetivo. Si tiene sentido, rodar con él. No optimice prematuramente su código.

0

Las vistas anidadas pueden tener sentido. Solo ten cuidado de no hacerlos demasiado generales.


vi un sistema que tenía una vista con 14 tablas mencionadas explícitamente, algunos de ellos relacionados con exterior autocombinaciones, y algunos de los 'cuadros' eran ellos mismos puntos de vista. No me gustó mucho, pero el DBMS lo hizo muy bien (dado que fue a finales de los 80). Una gran parte del esquema fue generado por una herramienta de modelado de datos.

CREATE VIEW IBB_V_Project AS 
    SELECT A.Project_Iref, 
      A.Section_Iref, 
      B.Section_Eref, 
      N.Company_Iref, 
      N.Company_Name, 
      A.Product_Desc, 
      A.Project_Type_Iref, 
      D.Project_Type, 
      A.Person_Iref, 
      F.Full_Name, 
      A.Respon_Iref, 
      G.Post_Location, 
      A.Project_Stat_Iref, 
      E.Project_Status, 
      A.Source_Iref, 
      I.Source, 
      A.Sic_Iref, 
      L.Sic_Eref, 
      A.Op_Activity_Iref, 
      M.Op_Activity_Desc, 
      A.Involve_Iref, 
      K.IBB_Involvement, 
      A.Nature_Iref, 
      C.Nature_Of_Next_Act, 
      A.Internat_Mobile, 
      A.Whether_Cop_Case, 
      A.Closed_Ind, 
      A.Next_Action_Date, 
      A.Creation_Date, 
      A.Last_Edit_Date, 
      A.Last_Editor_Iref, 
      H.Logname 

    FROM IBB_Project A, 
      IBB_Section B, 
      IBB_R_Proj_Type D, 
      IBB_R_Project_Stat E, 
      IBB_Personnel H, 
      OUTER IBB_R_Next_Act C, 
      OUTER IBB_Personnel F, 
      OUTER (IBB_Post_Respon X, OUTER IBB_V_Post_Resp2 G), 
      OUTER IBB_R_Source I, 
      OUTER IBB_R_Involvement K, 
      OUTER IBB_Sic L, 
      OUTER IBB_Op_Act M, 
      OUTER IBB_V_Proj_Co2 N 

    WHERE A.Section_Iref  = B.Section_Iref 
     AND A.Project_Type_Iref = D.Project_Type_Iref 
     AND A.Project_Stat_Iref = E.Project_Stat_Iref 
     AND A.Last_Editor_Iref = H.Person_Iref 
     AND A.Nature_Iref  = C.Nature_Iref 
     AND A.Person_Iref  = F.Person_Iref 
     AND A.Respon_Iref  = X.Respon_Iref 
     AND X.Respon_Iref  = G.Person_Iref 
     AND A.Source_Iref  = I.Source_Iref 
     AND A.Sic_Iref   = L.Sic_Iref 
     AND A.Op_Activity_Iref = M.Op_Activity_Iref 
     AND A.Project_Iref  = N.Project_Iref 
     AND A.Involve_Iref  = K.Involve_Iref; 

La notación de unión externa es específica de Informix (que ahora también admite la notación estándar de SQL).

Tenga en cuenta que ambas vistas son IBB_V_Post_Resp2 e IBB_V_Proj_Co2. De hecho, IBB_V_Proj_Co2 era una vista 3-mesa, detalles exactos desconocido, pero de la forma:

CREATE VIEW IBB_V_Proj_Co2 AS 
    SELECT A.Project_Iref, 
      A.Some_Other_Col col01, 
      B.Xxxx_Iref, 
      B.Some_Other_Col col02, 
      C.Yyyy_Iref, 
      C.Some_Other_Col col03 
    FROM IBB_Project A, 
      OUTER (IBB_R_Xxxx B, IBB_R_Yyyy C) 
    WHERE A.Xxxx_Iref = B.Xxxx_IrEf 
     AND B.Yyyy_Iref = C.Yyyy_Iref; 

Esto significa que la vista IBB_V_Project tiene un exterior autocombinación en IBB_Project. La vista IBB_V_Post_Resp2 probablemente también implicó 3 tablas (mis notas sobre eso no estaban claras, allá por 1993, cuando grabé esta información).

CREATE VIEW IBB_V_Post_Resp2 AS 
    SELECT A.Person_Iref, 
      A.Some_Other_Col col01, 
      B.Xxxx_Iref, 
      B.Some_Other_Col col02, 
      C.Yyyy_Iref, 
      C.Some_Other_Col col03 
    FROM IBB_Personnel A, 
      IBB_R_Xxxx B, 
      IBB_R_Yyyy C 
    WHERE A.Xxxx_Iref = B.Xxxx_Iref 
     AND B.Yyyy_Iref = C.Yyyy_Iref; 

Las columnas Zzzz_Iref eran o claves externas de serie o INTEGER referencia a una tecla SERIAL.

La definición de vista principal se refiere a 14 tablas, con 4 uniones internas y 9 uniones externas. Cuando se tienen en cuenta las vistas con referencias cruzadas, son 18 tablas en total, con 7 uniones internas y 10 uniones externas.

5

Voy a contestar desde una mejor perspectiva de las prácticas:

hay sólo unas pocas veces que se detenía sobre el uso de Vistas de los dictámenes.

  1. Nesting parece estar fuera de control ... más de 3 niveles de profundidad. La razón por la que estoy anidando es hacer que el código sea más fácil de mantener. Tan pronto como empiezo a llegar a este punto, comienza a sentirse un poco complicado de entender.

  2. Anidamiento de una vista que utiliza funciones analíticas. Personalmente, por una razón u otra, no he tenido muy buena experiencia con vistas de anidamiento con función analítica.

  3. Nidos de vistas que realizan escaneos completos por naturaleza.Si bien creo que el optimizador de consultas es probablemente lo suficientemente inteligente como para manejar esto, me parece mal cuando estoy revisando la lógica de la vista.

  4. El rendimiento es una gran preocupación. Esto no quiere decir que el optimizador pueda equivocarse, pero es decir, antes de lanzarlo, voy a probarlo para ver si no puedo encontrar una manera más rápida de hacerlo.

Aparte de eso, he utilizado las vistas de las vistas con bastante éxito.

0

realmente no quieren quedar atrapados en la vista anidada toda cosa

tienen un pensar en esto para una idea ... su tratando de unirse a una mesa para encontrar desajustes ... Me gustaría utilizar la función de Oracle 'menos' ... MINUS selecciona elementos de la primera tabla y luego elimina las filas que también son devueltas por la segunda instrucción SELECT.

num SELECT FROM (SELECT 1 AS num FROM DUAL UNION ALL selecciona 2 AS num FROM DUAL UNION ALL seleccionar 3 AS num FROM DUAL) base_view

MENOS

SELECT 2 AS num FROM DUAL

+0

Gracias por la respuesta, pero esto no es lo que realmente deseo. Habrá dos informes en los que se enumerarán diferentes tipos de información (a través de la agrupación), pero deben coincidir exactamente (en totales). No se utiliza para la detección de discrepancias, ambos son necesarios para sus propios fines, pero siempre deben basarse en los mismos números, incluso si las reglas para esos números cambian ligeramente en el futuro. – Galghamon

Cuestiones relacionadas