Balance de escritura y lectura de bases de datos

imagen

En un artículo anterior , describí el concepto y la implementación de una base de datos construida sobre la base de funciones, no tablas y campos como en las bases de datos relacionales. Dio muchos ejemplos que muestran las ventajas de este enfoque sobre el clásico. Muchos los encontraron no lo suficientemente convincentes.

En este artículo, mostraré cómo este concepto le permite equilibrar rápida y convenientemente la escritura y la lectura en la base de datos sin ningún cambio en la lógica del trabajo. Intentaron implementar una funcionalidad similar en DBMS comerciales modernos (en particular, Oracle y Microsoft SQL Server). Al final del artículo, mostraré lo que les sucedió, por decirlo suavemente, no muy.

Descripción


Como antes, para una mejor comprensión, comenzaré la descripción con ejemplos. Supongamos que necesitamos implementar una lógica que devuelva una lista de departamentos con el número de empleados en ellos y su salario total.

En una base de datos funcional, se verá así:
CLASS Department '';
name '' = DATA STRING [ 100 ] (Department);

CLASS Employee '';
department '' = DATA Department (Employee);
salary '' = DATA NUMERIC [ 10 , 2 ] (Employee);

countEmployees '- ' (Department d) =
GROUP SUM 1 IF department(Employee e) = d;
salarySum ' ' (Department d) =
GROUP SUM salary(Employee e) IF department(e) = d;

SELECT name(Department d), countEmployees(d), salarySum(d);
La complejidad de ejecutar esta consulta en cualquier DBMS será equivalente a O (número de empleados) , ya que para este cálculo debe escanear toda la tabla de empleados y luego agruparlos por departamento. También habrá una pequeña adición (creemos que hay muchos más empleados que departamentos) dependiendo del plan elegido O (número de registro de empleados) u O (número de departamentos) para la agrupación, etc.

Está claro que la sobrecarga para la ejecución puede ser diferente en diferentes DBMS, pero la complejidad no cambiará de ninguna manera.

En la implementación propuesta, el DBMS funcional formará una subconsulta, que calculará los valores necesarios para el departamento y luego se unirá a la tabla del departamento para obtener el nombre. Sin embargo, para cada función, al declarar, es posible especificar un marcador MATERIALIZADO especial. El sistema creará automáticamente un campo apropiado para cada función. Cuando cambia el valor de una función, el valor del campo cambiará en la misma transacción. Al acceder a esta función, ya se realizará una apelación al campo calculado.

En particular, si configura MATERIALIZADO para las funciones countEmployees y salarrySum , en la tabla con la lista de departamentos se agregarán dos campos en los que se almacenará el número de empleados y su salario total. Con cualquier cambio en los empleados, sus salarios o afiliación con los departamentos, el sistema cambiará automáticamente los valores de estos campos. La consulta anterior comenzará a acceder a estos campos directamente y se ejecutará para O (número de departamentos) .

¿Cuáles son las limitaciones? Solo una cosa: dicha función debe tener un número finito de valores de entrada para los que se define su valor. De lo contrario, será imposible construir una tabla que almacene todos sus valores, ya que no puede haber una tabla con un número infinito de filas.

Un ejemplo:
employeesCount ' > N' (Department d, NUMERIC [ 10 , 2 ] N) =
GROUP SUM salary(Employee e) IF department(e) = d AND salary(e) > N;
Esta función se define para un número infinito de valores del número N (por ejemplo, cualquier valor negativo es adecuado). Por lo tanto, no se puede poner MATERIALIZADO. Por lo tanto, esta es una limitación lógica y no técnica (es decir, no porque no hayamos podido implementar esto). De lo contrario, no hay restricciones. Puede usar la agrupación, la clasificación, AND y OR, PARTITION, recursión, etc.

Por ejemplo, en la tarea 2.2 del artículo anterior, puede poner MATERIALIZADO en ambas funciones:
bought '' (Customer c, Product p, INTEGER y) =
GROUP SUM sum(Detail d) IF
customer(order(d)) = c AND
product(d) = p AND
extractYear(date(order(d))) = y MATERIALIZED ;
rating '' (Customer c, Product p, INTEGER y) =
PARTITION SUM 1 ORDER DESC bought(c, p, y), p BY c, y MATERIALIZED ;
SELECT contactName(Customer c), name(Product p) WHERE rating(c, p, 1997 ) < 3 ;
El propio sistema creará una tabla con claves de los tipos Cliente , Producto e INTEGER , le agregará dos campos y actualizará los valores de los campos en ellos con cualquier cambio. Tras nuevas llamadas a estas funciones, no se calcularán, pero se leerán los valores de los campos correspondientes.

Con este mecanismo, puede, por ejemplo, deshacerse de la recursividad (CTE) en las consultas. En particular, considere los grupos que forman el árbol usando la relación hijo / padre (cada grupo tiene un enlace a su padre):
parent = DATA Group (Group);
En una base de datos funcional, la lógica de recursión se puede definir de la siguiente manera:
level (Group child, Group parent) = RECURSION 1l IF child IS Group AND parent == child
STEP 2l IF parent == parent($parent);
isParent (Group child, Group parent) = TRUE IF level(child, parent) MATERIALIZED ;
Dado que MATERIALIZED está fijado para la función isParent , se creará una tabla con dos claves (grupos), en la que el campo isParent será verdadero solo si la primera clave es descendiente de la segunda. El número de entradas en esta tabla será igual al número de grupos multiplicado por la profundidad promedio del árbol. Si es necesario, por ejemplo, calcular el número de descendientes de un determinado grupo, puede acceder a esta función:
childrenCount (Group g) = GROUP SUM 1 IF isParent(Group child, g);
No habrá CTE en la consulta SQL. En cambio, habrá un simple GROUP BY.

Con este mecanismo, también puede desnormalizar fácilmente la base de datos si es necesario:
CLASS Order '' ;
date '' = DATA DATE (Order);

CLASS OrderDetail ' ' ;
order '' = DATA Order (OrderDetail);
date '' (OrderDetail d) = date(order(d)) MATERIALIZED INDEXED ;
Cuando llame a la función de fecha para la línea de orden, la lectura será de la tabla con líneas de orden del campo para el que hay un índice. Al cambiar la fecha del pedido, el propio sistema recalculará automáticamente la fecha desnormalizada en la línea.

Los beneficios


¿Por qué se necesita todo este mecanismo? En los DBMS clásicos, sin reescribir consultas, un desarrollador o un DBA solo pueden cambiar índices, determinar estadísticas y decirle al planificador de consultas cómo ejecutarlos (además, las SUGERENCIAS están disponibles solo en DBMS comerciales). No importa cuánto lo intenten, no podrán cumplir la primera solicitud del artículo para O (número de departamentos) sin cambiar las solicitudes y agregar desencadenantes. En el esquema propuesto, en la etapa de desarrollo, no tiene que pensar en la estructura del almacenamiento de datos y qué agregaciones usar. Todo esto se puede cambiar fácilmente sobre la marcha, directamente en funcionamiento.

En la práctica, esto es lo siguiente. Algunas personas desarrollan lógica directamente basada en la tarea. No están versados ​​en algoritmos y su complejidad, ni en planes de ejecución, ni en tipos de join'ov, ni en ningún otro componente técnico. Estas personas son más analistas de negocios que desarrolladores. Luego, todo entra en pruebas u operación. El registro de consultas largas está habilitado. Cuando se detecta una solicitud larga, otras personas (más técnicas, de hecho DBA) deciden incluir MATERIALIZADO en alguna función intermedia. De este modo, la grabación se ralentiza un poco (ya que se requiere actualizar un campo adicional en una transacción). Sin embargo, no solo esta solicitud se acelera significativamente, sino también todas las demás que usan esta función. Al mismo tiempo, tomar una decisión sobre qué función particular materializar es relativamente simple. Dos parámetros principales: el número de posibles valores de entrada (exactamente cuántos registros habrá en la tabla correspondiente) y con qué frecuencia se usa en otras funciones.

Análogos


Los DBMS comerciales modernos tienen mecanismos similares: VISTA MATERIALIZADA con FAST REFRESH (Oracle) e INDEXED VIEW (Microsoft SQL Server). En PostgreSQL MATERIALIZED VIEW no se puede actualizar en una transacción, sino solo a pedido (e incluso con restricciones muy estrictas), por lo que no lo consideramos. Pero tienen varios problemas, lo que limita en gran medida su uso.

Primero, puede habilitar la materialización solo si ya ha creado una VISTA normal. De lo contrario, tendrá que volver a escribir las solicitudes restantes para acceder a la vista recién creada para poder utilizar esta materialización. O déjelo como está, pero será al menos ineficaz si hay ciertos datos ya calculados, pero muchas consultas no siempre los usan, sino que los calcula de nuevo.

En segundo lugar, tienen una gran cantidad de restricciones:

Oráculo
5.3.8.4 Restricciones generales sobre la actualización rápida

La consulta de definición de la vista materializada está restringida de la siguiente manera:
  • La vista materializada no debe contener referencias a expresiones no repetitivas como SYSDATE y ROWNUM .
  • La vista materializada no debe contener referencias a tipos de datos RAW o LONG RAW .
  • No puede contener una subconsulta de lista SELECT .
  • No puede contener funciones analíticas (por ejemplo, RANK ) en la cláusula SELECT .
  • No puede hacer referencia a una tabla en la que se define un índice XMLIndex .
  • No puede contener una cláusula MODEL .
  • No puede contener una cláusula HAVING con una subconsulta.
  • No puede contener consultas anidadas que tengan ANY , ALL o NOT EXISTS .
  • No puede contener una cláusula [START WITH …] CONNECT BY .
  • No puede contener varias tablas de detalles en diferentes sitios.
  • ON COMMIT las vistas materializadas no pueden tener tablas de detalles remotas.
  • Las vistas materializadas anidadas deben tener una unión o agregado.
  • Las vistas de unión materializadas y las vistas agregadas materializadas con una cláusula GROUP BY no se pueden seleccionar de una tabla organizada por índice.

5.3.8.5 Restricciones a la actualización rápida en vistas materializadas con combinaciones solamente

La definición de consultas para vistas materializadas solo con combinaciones y sin agregados tiene las siguientes restricciones para la actualización rápida:
  • Todas las restricciones de " Restricciones generales sobre la actualización rápida ".
  • No pueden tener cláusulas o agregados GROUP BY .
  • Los Rowids de todas las tablas en la lista FROM deben aparecer en la lista SELECT de la consulta.
  • Los registros de vista materializada deben existir con rowids para todas las tablas base en la lista FROM de la consulta.
  • No puede crear una vista materializada rápida y actualizable desde varias tablas con combinaciones simples que incluyen una columna de tipo de objeto en la instrucción SELECT .

Además, el método de actualización que elija no será óptimamente eficiente si:
  • La consulta de definición utiliza una combinación externa que se comporta como una combinación interna. Si la consulta de definición contiene dicha unión, considere reescribir la consulta de definición para que contenga una unión interna.
  • La lista SELECT de la vista materializada contiene expresiones en columnas de varias tablas.

5.3.8.6 Restricciones a la actualización rápida en vistas materializadas con agregados

La definición de consultas para vistas materializadas con agregados o combinaciones tiene las siguientes restricciones en la actualización rápida:

La actualización rápida es compatible con las vistas materializadas ON COMMIT y ON DEMAND , sin embargo, se aplican las siguientes restricciones:
  • Todas las tablas en la vista materializada deben tener registros de vista materializados, y los registros de vista materializada deben:
    • Contiene todas las columnas de la tabla referenciada en la vista materializada.
    • Especifique con ROWID e INCLUDING NEW VALUES .
    • Especifique la cláusula SEQUENCE si se espera que la tabla tenga una combinación de inserciones / cargas directas, eliminaciones y actualizaciones.

  • Solo SUM , COUNT , AVG , VARIANCE , VARIANCE , MIN y MAX son compatibles para una actualización rápida.
  • COUNT(*) debe especificarse.
  • Las funciones agregadas deben aparecer solo como la parte más externa de la expresión. Es decir, los agregados como AVG(AVG(x)) o AVG(x) + AVG(x) no están permitidos.
  • Para cada agregado como AVG(expr) , el COUNT(expr) correspondiente COUNT(expr) debe estar presente. Oracle recomienda que se especifique SUM(expr) .
  • Si se especifica STDDEV(expr VARIANCE(expr) o STDDEV(expr ), COUNT(expr) y SUM(expr) deben especificarse. Oracle recomienda que se especifique SUM(expr *expr) .
  • La columna SELECT en la consulta de definición no puede ser una expresión compleja con columnas de varias tablas base. Una posible solución a esto es usar una vista materializada anidada.
  • La lista SELECT debe contener todas las columnas GROUP BY .
  • La vista materializada no se basa en una o más tablas remotas.
  • Si usa un tipo de datos CHAR en las columnas de filtro de un registro de vista materializada, los juegos de caracteres del sitio maestro y la vista materializada deben ser los mismos.
  • Si la vista materializada tiene uno de los siguientes, la actualización rápida solo es compatible con inserciones DML convencionales y cargas directas.
    • Vistas materializadas con agregados MIN o MAX
    • Vistas materializadas que tienen SUM(expr) pero no COUNT(expr)
    • Vistas materializadas sin COUNT(*)

    Dicha vista materializada se denomina vista materializada de solo inserción.
  • Una vista materializada con MAX o MIN se puede actualizar rápidamente después de eliminar o mezclar sentencias DML si no tiene una cláusula WHERE .
    La actualización rápida máxima / mínima después de eliminar o mezclar DML no tiene el mismo comportamiento que el caso de solo inserción. Elimina y vuelve a calcular los valores máximos / mínimos para los grupos afectados. Debe ser consciente de su impacto en el rendimiento.
  • Las vistas materializadas con vistas con nombre o subconsultas en la cláusula FROM se pueden actualizar rápidamente siempre que las vistas se puedan combinar por completo. Para obtener información sobre qué vistas se combinarán, consulte la Referencia del lenguaje SQL de la base de datos Oracle .
  • Si no hay combinaciones externas, puede tener selecciones arbitrarias y combinaciones en la cláusula WHERE .
  • Las vistas agregadas materializadas con uniones externas se pueden actualizar rápidamente después de DML convencional y cargas directas, siempre que solo se haya modificado la tabla externa. Además, deben existir restricciones únicas en las columnas de unión de la tabla de unión interna. Si hay uniones externas, todas las uniones deben estar conectadas por AND sy deben usar el operador de igualdad ( = ).
  • Para las vistas materializadas con CUBE , ROLLUP , conjuntos de agrupación o concatenación de ellas, se aplican las siguientes restricciones:
    • La lista SELECT debe contener un distintivo de agrupación que puede ser una función GROUPING_ID en todas las expresiones GROUP BY o funciones GROUPING una para cada expresión GROUP BY . Por ejemplo, si la cláusula GROUP BY de la vista materializada es " GROUP BY CUBE(a, b) ", la lista SELECT debe contener " GROUPING_ID(a, b) " o " GROUPING(a) AND GROUPING(b) "para que la vista materializada se actualice rápidamente.
    • GROUP BY no debe dar lugar a agrupaciones duplicadas. Por ejemplo, " GROUP BY a, ROLLUP(a, b) " no se puede actualizar rápidamente porque da como resultado agrupaciones duplicadas " (a), (a, b), AND (a) ".

5.3.8.7 Restricciones a la actualización rápida en vistas materializadas con UNION ALL

Las vistas materializadas con el operador conjunto UNION ALL admiten la opción REFRESH FAST si se cumplen las siguientes condiciones:
  • La consulta de definición debe tener el operador UNION ALL en el nivel superior.

    El operador UNION ALL no se puede incrustar dentro de una subconsulta, con una excepción: UNION ALL puede estar en una subconsulta en la cláusula FROM siempre que la consulta de definición tenga la forma SELECT * FROM (vista o subconsulta con UNION ALL ) como en el siguiente ejemplo:
      CREAR VISTA view_with_unionall AS
     (SELECCIONE c.rowid crid, c.cust_id, 2 umarker
      DE clientes c DONDE c.cust_last_name = 'Smith'
      UNIÓN TODO
      SELECCIONE c.rowid crid, c.cust_id, 3 umarker
      DE clientes c DONDE c.cust_last_name = 'Jones');
    
     CREAR VISTA MATERIALIZADA unionall_inside_view_mv
     ACTUALIZACIÓN RÁPIDA EN LA DEMANDA
     SELECCIONAR * DESDE view_with_unionall;
    
    Tenga en cuenta que la vista view_with_unionall cumple los requisitos para una actualización rápida.
  • Cada bloque de consulta en la consulta UNION ALL debe cumplir los requisitos de una vista materializada rápida y actualizable con agregados o una vista materializada rápida y renovable con uniones.

    Los registros de vista materializada apropiados se deben crear en las tablas según sea necesario para el tipo correspondiente de vista materializada rápida y actualizable.
    Tenga en cuenta que la base de datos Oracle también permite el caso especial de una vista materializada de una sola tabla con combinaciones solo si la columna ROWID se ha incluido en la lista SELECT y en el registro de vista materializada. Esto se muestra en la consulta de definición de la vista view_with_unionall .
  • La lista SELECT de cada consulta debe incluir un marcador UNION ALL , y la columna UNION ALL debe tener un valor numérico o de cadena constante diferente en cada rama UNION ALL . Además, la columna de marcador debe aparecer en la misma posición ordinal en la lista SELECT de cada bloque de consulta. Consulte " Marcador de UNION ALL y reescritura de consultas " para obtener más información sobre los marcadores UNION ALL .
  • Algunas funciones, como las uniones externas, las consultas de vistas materializadas agregadas de solo inserción y las tablas remotas no son compatibles con las vistas materializadas con UNION ALL . Sin embargo, tenga en cuenta que las vistas materializadas utilizadas en la replicación, que no contienen uniones o agregados, pueden actualizarse rápidamente cuando se utilizan UNION ALL o tablas remotas.
  • El parámetro de inicialización de compatibilidad debe establecerse en 9.2.0 o superior para crear una vista materializada rápida y actualizable con UNION ALL .

No quiero ofender a los fanáticos de Oracle, pero a juzgar por su lista de limitaciones, parece que este mecanismo no se escribió en el caso general utilizando algún tipo de modelo, sino miles de indios, donde a todos se les permitió escribir su propio hilo, y cada uno de ellos pudo y lo hizo Usar este mecanismo para una lógica real es como caminar en un campo minado. En cualquier momento, puede obtener una mina, golpeando una de las limitaciones no obvias. Cómo funciona esto también es un tema aparte, pero está fuera del alcance de este artículo.

Microsoft SQL Server

Requerimientos Adicionales


Además de las opciones SET y los requisitos de la función determinista, se deben cumplir los siguientes requisitos:
  • El usuario que ejecuta CREATE INDEX debe ser el propietario de la vista.
  • Cuando crea el índice, la opción IGNORE_DUP_KEY debe establecerse en OFF (la configuración predeterminada).
  • Las tablas deben estar referenciadas por nombres de dos partes, esquema . nombre de tabla en la definición de vista.
  • Las funciones definidas por el usuario a las que se hace referencia en la vista deben crearse utilizando la opción WITH SCHEMABINDING .
  • Cualquier función definida por el usuario a la que se haga referencia en la vista debe estar referenciada por nombres de dos partes, <schema> . <función> .
  • La propiedad de acceso a datos de una función definida por el usuario debe ser NO SQL , y la propiedad de acceso externo debe ser NO .
  • Las funciones de Common Language Runtime (CLR) pueden aparecer en la lista de selección de la vista, pero no pueden ser parte de la definición de la clave de índice agrupada. Las funciones CLR no pueden aparecer en la cláusula WHERE de la vista o en la cláusula ON de una operación JOIN en la vista.
  • Las funciones y métodos CLR de los tipos definidos por el usuario CLR utilizados en la definición de vista deben tener las propiedades establecidas como se muestra en la siguiente tabla.
    PropiedadNota
    DETERMINISTICA = VERDADERODebe declararse explícitamente como un atributo del método Microsoft .NET Framework.
    PRECISO = VERDADERODebe declararse explícitamente como un atributo del método .NET Framework.
    ACCESO A DATOS = NO SQLDeterminado estableciendo el atributo DataAccess en DataAccessKind.None y el atributo SystemDataAccess en SystemDataAccessKind.None.
    ACCESO EXTERNO = NOEsta propiedad por defecto es NO para las rutinas CLR.
  • La vista debe crearse utilizando la opción WITH SCHEMABINDING .
  • La vista debe hacer referencia solo a las tablas base que están en la misma base de datos que la vista. La vista no puede hacer referencia a otras vistas.
  • La instrucción SELECT en la definición de vista no debe contener los siguientes elementos de Transact-SQL:
    COUNTFunciones de ROWSET ( OPENDATASOURCE , OPENQUERY , OPENROWSET Y OPENXML )OUTER une ( LEFT , RIGHT o FULL )
    Tabla derivada (definida al especificar una instrucción SELECT en la cláusula FROM )AutounionesEspecificar columnas usando SELECT * o SELECT <table_name>.*
    DISTINCTSTDEV , STDEVP , VAR , VARP o AVGExpresión de tabla común (CTE)
    flotante 1 , texto , ntext , imagen , XML o columnas de flujo de archivosSubconsultaCláusula OVER , que incluye funciones de clasificación o ventana agregada
    Predicados de texto completo ( CONTAINS , FREETEXT )Función SUM que hace referencia a una expresión anulableORDER BY
    Función agregada definida por el usuario CLRTOPROLLUP CUBE , ROLLUP o ROLLUP GROUPING SETS
    MIN , MAXOperadores UNION , EXCEPT o INTERSECTTABLESAMPLE
    Variables de la tablaOUTER APPLY o CROSS APPLYPIVOT , UNPIVOT
    Conjuntos de columnas dispersasFunciones en línea (TVF) o con valores de tabla de varias instrucciones (MSTVF)OFFSET
    CHECKSUM_AGG

    1 La vista indizada puede contener columnas flotantes ; sin embargo, tales columnas no se pueden incluir en la clave de índice agrupado.
  • Si GROUP BY está presente, la definición VIEW debe contener COUNT_BIG(*) y no debe contener HAVING . Estas restricciones de GROUP BY son aplicables solo a la definición de vista indizada. Una consulta puede usar una vista indizada en su plan de ejecución incluso si no cumple con estas restricciones GROUP BY .
  • Si la definición de vista contiene una cláusula GROUP BY , la clave del índice agrupado único puede hacer referencia solo a las columnas especificadas en la cláusula GROUP BY .

Aquí puede ver que los indios no se sintieron atraídos, ya que decidieron hacerlo de acuerdo con el esquema "haremos poco, pero bien". Es decir, tienen más minas en el campo, pero su ubicación es más transparente. Lo más angustiante es esta limitación:
La vista debe hacer referencia solo a las tablas base que están en la misma base de datos que la vista. La vista no puede hacer referencia a otras vistas.

En nuestra terminología, esto significa que una función no puede acceder a otra función materializada. Corta toda la ideología de raíz.
Además, esta limitación (y más adelante en el texto) reduce en gran medida los casos de uso:
La instrucción SELECT en la definición de vista no debe contener los siguientes elementos de Transact-SQL:
COUNTFunciones de ROWSET ( OPENDATASOURCE , OPENQUERY , OPENROWSET Y OPENXML )OUTER une ( LEFT , RIGHT o FULL )
Tabla derivada (definida al especificar una instrucción SELECT en la cláusula FROM )AutounionesEspecificar columnas usando SELECT * o SELECT <table_name>.*
DISTINCTSTDEV , STDEVP , VAR , VARP o AVGExpresión de tabla común (CTE)
flotante 1 , texto , ntext , imagen , XML o columnas de flujo de archivosSubconsultaCláusula OVER , que incluye funciones de clasificación o ventana agregada
Predicados de texto completo ( CONTAINS , FREETEXT )Función SUM que hace referencia a una expresión anulableORDER BY
Función agregada definida por el usuario CLRTOPROLLUP CUBE , ROLLUP o ROLLUP GROUPING SETS
MIN , MAXOperadores UNION , EXCEPT o INTERSECTTABLESAMPLE
Variables de la tablaOUTER APPLY o CROSS APPLYPIVOT , UNPIVOT
Conjuntos de columnas dispersasFunciones en línea (TVF) o con valores de tabla de varias instrucciones (MSTVF)OFFSET
CHECKSUM_AGG

OUTER JOINS, UNION, ORDER BY y otros están prohibidos. Quizás fue más fácil indicar qué se puede usar que qué no. La lista probablemente sería mucho más pequeña.

Para resumir: un gran conjunto de restricciones en cada DBMS (noto comercial) versus ninguno (con la excepción de uno lógico en lugar de técnico) en la tecnología LGPL. Sin embargo, debe tenerse en cuenta que implementar este mecanismo en la lógica relacional es algo más complicado que en el funcional descrito.

Implementación


Como funciona PostgreSQL se utiliza como una "máquina virtual". En el interior hay un algoritmo complejo que genera consultas. Aquí está el código fuente . Y no solo hay un gran conjunto de heurísticas con un montón de ifs. Entonces, si tiene un par de meses para estudiar, puede intentar comprender la arquitectura.

¿Funciona de manera eficiente? Efectivamente suficiente. Desafortunadamente, probar esto es difícil. Solo puedo decir que si considera las miles de solicitudes que se encuentran en aplicaciones grandes, en promedio son más efectivas que un buen desarrollador. Un excelente programador de SQL puede escribir cualquier consulta de manera más eficiente, pero con mil consultas, simplemente no tendrá la motivación ni el tiempo para hacerlo. Lo único que puedo dar ahora como evidencia de efectividad es que, sobre la base de la plataforma construida en este DBMS, varios proyectos del sistema ERP funcionan en los que hay miles de funciones MATERIALIZADAS diferentes, con miles de usuarios y bases de datos de terrabyte con cientos de millones de registros funcionando en un servidor de doble procesador normal. Sin embargo, cualquiera puede probar / refutar la efectividad descargando la plataforma y PostgreSQL, permitiendo el registro de consultas SQL e intentando cambiar la lógica y los datos allí.

En los siguientes artículos, también hablaré sobre cómo puede colgar restricciones en las funciones, trabajar con sesiones de cambio y mucho más.

Source: https://habr.com/ru/post/459066/


All Articles