Contactos

1s 8 solicitud de lote. Solicitudes simples. Motivos del rendimiento de consulta subóptimo

Analicemos cómo la sintaxis de los textos de solicitudes de ejemplo sencillo: Documento retenido Consumible que contiene en la parte tabular Bienes lista de productos a la venta y cantidad. Al realizar dicho documento, es necesario garantizar el control de los saldos negativos almacenados en el registro de acumulación de saldos. Restos de Mercancías.

La estructura de configuración se muestra en la figura.

(16,22 kilobytes) Número de descargas: 64

Formemos una consulta a la parte tabular del documento y la tabla virtual Restos registro de acumulación. Tendremos en cuenta posibles líneas duplicadas en el documento, para ello agruparemos los registros.

Solicitud = Nueva Solicitud;
Solicitud.Texto = "
|ELIGE
| Doc. Nomenclatura,
| SUM(Cantidad Doc.) AS Cantidad_Documento,
| MINIMUM(ISNULL(Reg.NumberRemainder,0)) COMO Reg_Number
| DESDE
| Documento.Productos.consumibles AS Doc
| UNIRSE A LA IZQUIERDA
| Registro de Acumulación.Restos de Bienes.Restos() AS Reg
| EN
| Doc.Nomenclatura = Reg.Nomenclatura
|DONDE
| Enlace = &Enlace
|GROUP BY Doc.Nomenclatura";

// Pasar por el registro

FinCiclo;

Procedimiento final

Naturalmente, la solicitud resultante no es en absoluto óptima. Optimicémoslo con la ayuda de consultas anidadas: agrupemos la parte tabular del documento antes de conectarnos a la tabla de balance, pasemos la lista de bienes a los parámetros de la tabla virtual como el valor de la condición para calcular el balance. En consecuencia, nuestra solicitud tomará la siguiente forma:

|ELIGE
| Doc. Nomenclatura,

| DESDE
| (SELECCIONE

| DESDE
| Documento.Bienes.consumibles
| DONDE
| Enlace = &Enlace
| GRUPO POR Nomenclatura) COMO Doc
| UNIRSE A LA IZQUIERDA
Nomenclatura B
| (ELIGE DIFERENTES
| Nomenclatura
| DESDE
| Documento.Bienes.consumibles
| DONDE
| Vínculo = &Vínculo)) COMO registro
| EN

Si en una consulta fuera necesario obtener datos de restos de diferentes registros, entonces el valor del filtro, y por tanto nuestra segunda subconsulta, se repetiría en todos los parámetros de las tablas virtuales, es natural que el sistema vuelva a acceder a la base de datos. para cada subconsulta para obtener datos.

Mesas temporales

No recuerdo a partir de qué versión se hizo posible usar tablas temporales en las consultas. Para ello, se utiliza el objeto "Administrador de tablas temporales". De hecho, el administrador de tablas temporales describe el espacio de nombres de las tablas temporales y es responsable de crearlas y destruirlas en la base de datos.

Las tablas temporales en sí mismas se crean físicamente en la base de datos, por lo tanto, deben tratarse con precaución, ya que el subsistema de disco es actualmente la parte más lenta de la tecnología, y la velocidad de creación y destrucción de tablas depende directamente de ello.

Reescribamos la consulta para usar tablas temporales. Coloquemos la parte tabular agrupada del documento y la lista de productos para el filtro de tablas virtuales en tablas temporales:

Publicación de manejo de procedimientos (falla, modo de publicación)

MBT = Nuevo Administrador de Tablas Temporales;

Solicitud = Nueva Solicitud;
Solicitud.Texto = "
|ELIGE
| Nomenclatura, SUM(Cantidad) AS Cantidad
|PONER DOCUMENTO
| DESDE
| Documento.Bienes.consumibles
|DONDE
| Enlace = &Enlace
|GRUPO POR Nomenclatura";

Solicitud = Nueva Solicitud;
Query.TemporaryTable Manager = MBT;
Query.Text = "SELECCIONE DIFERENTE
| Nomenclatura
|PUT lista de productos
| DESDE
| Documento.Bienes.consumibles
|DONDE
| Enlace = &Enlace";

Solicitud = Nueva Solicitud;
Query.TemporaryTable Manager = MBT;
Solicitud.Texto = "
|ELIGE
| Doc. Nomenclatura,
| Doc.Cantidad AS Doc_Cantidad,
| ISNULL(Reg.NumberRemainder,0) COMO Reg_Number
| DESDE
| Doc CÓMO Doc
| UNIRSE A LA IZQUIERDA
| Registro de Acumulación.Restos de Mercancías.Restos(,
| Nomenclatura
| DESDE
| EN
| Doc.Nomenclatura = Reg.Nomenclatura";

Resultado de la consulta = Consulta. Ejecutar ();
Selección = QueryResult.Select();

Mientras Selección.Siguiente() Bucle

//Comprobar saldos negativos

// Pasar por el registro

FinCiclo;

Procedimiento final

Cuando use tablas temporales en el texto de la consulta, use la instrucción Correo para crear una nueva tabla temporal, en este caso, el sistema no envía el contenido de esta tabla al resultado de la consulta (ver nota 1 y nota 2 en el texto anterior), sino la cantidad de registros colocados en la tabla temporal, usted No puede aceptar este valor si lo desea.

También puede utilizar la instrucción Destruir en este caso, la tabla temporal se destruye; de ​​lo contrario, las tablas temporales se destruyen junto con el objeto del administrador de tablas temporales.

En nuestra consulta principal, utilicé los nombres de las tablas temporales como indicación de la fuente de adquisición de datos (se les debe asignar un sinónimo, que vemos en el texto). Puede usar tablas temporales como fuente más de una vez, lo que, si se usa hábilmente, reducirá el texto de la consulta (mejorará la legibilidad de consultas complejas) y aumentará la velocidad (al usar datos de tablas temporales en varios lugares de la consulta).

solicitudes por lotes

Las consultas por lotes complementan lógicamente la funcionalidad de las tablas temporales y brindan más opciones cuando se trabaja con consultas.

En una consulta por lotes, de hecho, puede describir varias consultas, tanto relacionadas entre sí mediante tablas temporales como no relacionadas (es posible, pero no está claro por qué). Como resultado, puede ejecutar todas las consultas secuencialmente y recibir como resultado una matriz con los resultados de cada ejecución de consulta o el resultado de la última. Para obtener una matriz con los resultados de la consulta, utilice el método EjecutarPaquete() objeto de solicitud, y para obtener el resultado de la última solicitud EjecutarSolicitud().

En el texto de la solicitud, las solicitudes de paquetes están separadas por el símbolo ";" (punto y coma). Solo hay un espacio de nombres de tabla virtual por consulta por lotes. No se requiere el uso de un administrador de tablas temporales, pero es posible si desea transferir tablas temporales de una consulta por lotes a otra.

Reescribamos el procedimiento para usar consultas por lotes:

Publicación de manejo de procedimientos (falla, modo de publicación)

Solicitud = Nueva Solicitud;
Solicitud.Texto = "
|ELIGE
| Nomenclatura, SUM(Cantidad) AS Cantidad
|PONER DOCUMENTO
| DESDE
| Documento.Bienes.consumibles
|DONDE
| Enlace = &Enlace
|GRUPO POR Nomenclatura
|;
|ELIGE DIFERENTE
| Nomenclatura
|PUT lista de productos
| DESDE
| Documento.Bienes.consumibles
|DONDE
| Enlace = &Enlace
|;
|ELIGE
| Doc. Nomenclatura,
| Doc.Cantidad AS Doc_Cantidad,
| ISNULL(Reg.NumberRemainder,0) COMO Reg_Number
| DESDE
| Doc CÓMO Doc
| UNIRSE A LA IZQUIERDA
| Registro de Acumulación.Restos de Mercancías.Restos(,
| Nomenclatura B(ELIJA DIFERENTE
| Nomenclatura
| DESDE
| Lista de bienes AS Lista de bienes)) AS Reg
| EN
| Doc.Nomenclatura = Reg.Nomenclatura";

Mientras Selección.Siguiente() Bucle

//Comprobar saldos negativos

// Pasar por el registro

FinCiclo;

Procedimiento final

De hecho, eliminé la definición del objeto de consulta y el uso del administrador de tablas temporales, combiné los textos de consulta (preste atención al separador ";" entre los textos). Como resultado, el texto de la consulta se ha vuelto más legible (y cuando se usa el generador de consultas, la legibilidad de la consulta mejora considerablemente).

Después de ejecutar la solicitud a la variable ArrayResults tenemos 3 elementos. Los dos primeros contendrán un número que caracteriza el número de registros colocados en tablas temporales DocPM Y Lista de productos, y el tercero contendrá una selección con campos Nomenclatura, Doc_ Cantidad y Reg_ Cantidad.

en una variable Resultado de la solicitud sólo se incluirá una muestra.

Bueno, eso es todo para las solicitudes por lotes. Un mecanismo muy conveniente tanto para escribir consultas como para leer consultas complejas.

La plataforma 1C Enterprise le permite ejecutar varias consultas secuencialmente a la vez. En 1C, esto se denomina lote de solicitudes. Dentro de un paquete, cada solicitud está separada por un "punto y coma".

Para lograr la ejecución por etapas de consultas en un lote, por regla general, inicialmente se crean tablas temporales, luego se forman las condiciones para su uso conjunto, como filtros, uniones, uniones. Gracias a esto, se logra el resultado final. Las tablas temporales obtenidas como resultado de cualquier consulta en el lote continúan existiendo hasta el final de la ejecución del paquete como un todo o hasta la ejecución de una consulta que destruye las tablas temporales.

Además, el uso de consultas por lotes y tablas temporales mejora en gran medida la legibilidad de todo el código. Las consultas complejas que también contienen consultas anidadas pueden ser muy difíciles de entender. Sin embargo, si divide una consulta larga y compleja en varias, e incluso utiliza tablas temporales, esto no solo mejorará la percepción, sino que en la mayoría de los casos conducirá a un mayor rendimiento.

Otro detalle importante a favor de las solicitudes por lotes en 1C es que, al contrario, podemos obtener el resultado de cada solicitud en un lote por separado.

Un ejemplo de creación de un lote de solicitudes en lenguaje 1C

Para ver un ejemplo de cómo crear un lote de consultas, usaremos el generador de consultas, al que llamaremos para mayor claridad desde la consola de consultas. Así, podemos ver inmediatamente el resultado de la ejecución del paquete.

Vamos a crear una solicitud por lotes simple. Sugiero insertar inmediatamente el texto de la solicitud en y luego abrirlo y ver cómo se forma el paquete de solicitud. Agregue una nueva solicitud a la consola y pegue el siguiente texto:

Obtenga lecciones en video de 267 1C gratis:

Autosuficiente.Enlace,
Autosuficiente Padre,
Autosuficiente.Código,
Autosuficiente.Código QuickChoice,
Autosuficiente Nombre,
Autosuficiente.Ver,
Autosuficiente Fuera de balance,
Autosuficiente Cuantitativo,
DESDE
Plan de Cuentas Autosuficiente AS Autosuficiente
DONDE
Autosuficiente.Enlace = &Cuenta
;
////////////////////////////////////////////////////////////////////////////////

SELECCIONE
Self-supportingTypesSubconto.LineNumber AS LineNumber,
Tipos de subconto autoportantes Tipo de subconto AS Tipo de subconto,
Autosoportado Tipos de Subconto.Tipo de Subconto.Descripción AS Nombre,
Tipos de subconto autoportantes.Tipo de subconto.ValueType AS ValueType,
AutoportantesTipos de Subconto.Solo Volquetes AS SoloVolquetes,
Self-supportingTypesSubconto.Sum AS Sum
DESDE
Plan de Cuentas Autosustentable Tipos de Subconto AS Autosustentable
DONDE
Self-supportingTypesSubconto.Reference = &Cuenta
ORDENAR POR
AutosuficienteTypesSubconto.LineNumber

Para mí se ve así:

Ahora pasemos al generador de consultas. Aquí nos interesará la pestaña "Solicitudes de paquetes":

Como puede ver, tenemos un lote de dos solicitudes. Al hacer doble clic en cualquiera de ellos, puede proceder a editarlo:

Presionemos el botón "OK" e intentemos ver el resultado de la consulta por lotes.

Configure el parámetro "Cuenta". Puede seleccionar cualquier cuenta del plan de cuentas. Como probablemente ya haya adivinado, este lote de solicitudes debería obtener las propiedades de la cuenta. Haga clic en "Ejecutar" y vea el resultado:

Métodos Execute() y ExecutePackage()

Cuando mi consulta se volvió tan compleja que excedía mi comprensión, decidí utilizar consultas por lotes.

Pero ante el hecho de que no sé nada acerca de ellos. Resultó que todo es muy simple. En 5 minutos podrás utilizar consultas por lotes. Empieza a leer.

Al final resultó que, todo es muy simple. Solo necesita escribir varias consultas separadas por punto y coma. El resultado se devolverá en la última solicitud.

Las solicitudes por lotes aparecieron solo en la versión 8.1.11.67.4.

Este es el texto de la solicitud:

SELECCIONE T1.Zn PONER WTLetras DESDE (ELIJA "A" COMO ZN COMBINAR TODO SELECCIONE "B") COMO T1;

SELECCIONE T1.Zn COLOQUE WTCigures DESDE (SELECCIONE "1" COMO Zn COMBINE TODO SELECCIONE "2") COMO T1;

SELECCIONE TB.Zn, TTs.Zn, TB.Zn+TP.Zn DESDE VTBletters COMO TB, VTSigers COMO TP

Las consultas por lotes son compatibles con cualquier consola de consultas normal.

La figura muestra una ejecución de consulta de muestra:

Y ahora un poco por experiencia. Por qué se necesitan solicitudes por lotes.

El hecho es que puede poner algún resultado intermedio en una tabla temporal, que luego puede ser necesario en varias consultas posteriores.

Anteriormente, cuando no había tablas temporales, tenía que duplicar el texto de la consulta.

Por supuesto, puede prescindir de una consulta por lotes ejecutando secuencialmente varias consultas y manipulando tablas anidadas. Pero con las solicitudes por lotes es más conveniente. Simplemente escriba una consulta y no piense en colocar tablas temporales. Todo sucede por sí mismo.

Además, si se utiliza un sistema de composición de datos (DCS), selecciona de manera inteligente los campos requeridos y minimiza todo el lote de consultas.

Si las solicitudes tuvieran un método Solicitud.Ejecutar() ahora hay un metodo Solicitud.ExecutePackage(), que devuelve todas las tablas del lote, como una matriz.

El anuncio de las solicitudes por lotes en el sitio web de 1c está aquí: http://v8.1c.ru/overview/release_8_1_11/#Funcional

Historia de la vida

Permítanme explicar lo que me llevó a las solicitudes por lotes.

Entonces, imagina que hay un documento, tiene parte tabular. en una columna" Error» firmar, si hay un error al completar el documento. en una columna" Errores de texto» puede haber una o más frases con texto de error. Los tipos de errores contenidos en las oraciones se conocen de antemano.

Entonces, ingresamos una lista de todos los errores en la tabla. Códigos de error- contiene el código de error y la subcadena de búsqueda.

Obtenemos uno, dos o más errores por cada línea. Porque Puede haber múltiples errores en una línea.

Pero es posible que no se reconozca el error, es decir, bandera " Error” permanece, pero el texto de error no nos dio un código de error.

Hacemos una combinación izquierda, donde el código de error es NULL, le damos el código de error " Otros errores» .

Pero el problema fue que hubo alrededor de 200 códigos de error, por lo que la conexión izquierda funcionó durante mucho tiempo. Tuve que reemplazarlo con una conexión interna que voló. Pero al mismo tiempo, se perdieron líneas para las que no se encontró el error. Todavía no podía encontrar la manera de incorporar estas líneas en el resultado.

La consulta se escribió para el sistema de enlace, es decir, en principio no se pueden utilizar tablas de valores ni tablas temporales. Aquí es donde las solicitudes por lotes son útiles.

Simplemente conecté todas las líneas con errores nuevamente con todas las líneas para las que se encontraron errores, y aún así agregué el tipo de error "Otros errores".

El artículo describe el mecanismo de solicitudes por lotes implementado en la plataforma 1C:Enterprise. Después de leer el artículo, aprenderá:

  • ¿Qué son las solicitudes por lotes y para qué sirven?
  • ¿Cómo crear un paquete de consultas usando el generador de consultas?
  • ¿Cómo devolver una matriz de resultados para cada solicitud de un lote?

Aplicabilidad

El material es relevante para las versiones actuales de la plataforma 1C:Enterprise, edición 8.3

Propósito de un paquete de solicitud

La plataforma le permite trabajar con lotes de solicitudes. Tenemos la oportunidad de ejecutar varias solicitudes "a la vez". En una solicitud por lotes, los textos de la solicitud están separados por el símbolo ";" (punto y coma).

Las consultas se ejecutan secuencialmente, mientras que las tablas temporales que se crearon durante la ejecución de una consulta existirán hasta el final de la ejecución de todo el lote de consultas o hasta la ejecución de una consulta en el lote que destruya esta tabla temporal. diferencia importante de una consulta anidada es que los resultados de cada consulta del paquete están disponibles por separado.

Los lotes de consultas le permiten lograr la ejecución de consultas por etapas. Para ello, en una consulta por lotes primero se crean tablas temporales, luego se comparten (join, union, filtros) para obtener el resultado final de la consulta. También es importante tener en cuenta que el uso de tablas temporales en consultas por lotes mejora la legibilidad del cuerpo de la consulta.

Las consultas grandes con consultas anidadas envueltas unas dentro de otras suelen ser bastante difíciles de entender. Pero si reescribe una consulta de este tipo utilizando tablas temporales, la visibilidad de la consulta puede aumentar bastante. El uso de un paquete de consultas con tablas temporales también puede mejorar el rendimiento de las consultas.

Existen técnicas de optimización del rendimiento de consultas basadas en la sustitución de consultas anidadas por tablas temporales.

Una tabla temporal puede ser útil cuando necesita usar los mismos datos varias veces en una consulta grande, como unir o unir con otras tablas. Al usar consultas anidadas, dichos datos tendrían que obtenerse varias veces usando las mismas consultas anidadas, lo que, por supuesto, afectaría tanto la legibilidad del texto como el rendimiento.

Crear un paquete de consulta usando el constructor

Las solicitudes separadas incluidas en el paquete están separadas en el texto por el símbolo ";" (punto y coma). Para evitar dividir el cuerpo de la consulta manualmente, puede usar Query Builder para esto.
El generador de consultas tiene una pestaña separada para paquetes de consultas. Las solicitudes se pueden agregar al paquete usando el botón correspondiente en la barra de comandos, así como moverlas hacia arriba o hacia abajo.

Visualización de consultas individuales: pestañas en el lado derecho del constructor, con las que puede proceder a editar el texto de una consulta en particular. Los nombres se muestran en estas pestañas para tablas temporales, para solicitudes de selección de datos: "Solicitud de paquete 2", etc., para eliminación: "- NameVT".

También en la lista de tablas de la base de datos aparecen tablas temporales creadas dentro este paquete. Sin embargo, esto no significa que las tablas temporales se almacenen en la base de datos junto con todas las demás tablas de la base de datos.

Ejecución de solicitudes de paquetes

si el objeto Consulta ejecutar la consulta por lotes tiene instalado un administrador de tablas temporales, las tablas temporales que no se destruyeron como parte de la consulta por lotes se guardarán en el administrador instalado.

En el texto de una consulta por lotes, es posible usar y destruir tablas temporales que existían en el administrador de tablas temporales instalado en el momento en que se lanzó el lote para su ejecución.

Además del método Ejecutar(), que ejecuta secuencialmente todas las solicitudes del paquete y devuelve el resultado de la última solicitud en el paquete, hay otro método en la plataforma: EjecutarPaquete().

Este método ejecuta todas las consultas en secuencia y devuelve una matriz de resultados para cada consulta del paquete, en el orden en que aparecen las consultas en el cuerpo del paquete.

El resultado de ejecutar una solicitud para destruir una tabla temporal es el valor Indefinido, que también se coloca en la matriz de resultados.

Este artículo está dirigido a lectores que están familiarizados con el lenguaje SQL.

El lenguaje de consulta en 1C, que se ha utilizado desde la versión 8, ahora se ha convertido Herramienta útil para trabajar con bases de datos, lo que le permite leer de ellas, pero no escribir. Sintácticamente, el lenguaje de consulta es muy similar al lenguaje SQL, pero en ruso.

A continuación se muestra una tabla de correspondencia entre los principales operadores del lenguaje de consulta y SQL:

Operadores de lenguaje de consulta 1C

instrucción SQL

VARIOS

COMPUESTO

AGRUPAR POR

UNIR

ORDENAR POR

Y está lejos de Lista llena. Más completo información de contexto en operadores disponibles El lenguaje de consulta se puede obtener en el generador de consultas, que se analizará a continuación.

Ejecución de una petición 1C de código de programa se lleva a cabo utilizando el objeto de lenguaje integrado "Solicitud". Un ejemplo de cómo escribir una consulta de base de datos utilizando el lenguaje de programación integrado:

Solicitud = Nueva Solicitud; Query.Text = "ELEGIR | Sinónimo.Referencia COMO Referencia | DE | Catálogo.Directorio1 COMO Sinónimo"; Selección = Consulta.Ejecutar().Seleccionar(); Mientras Selection.Next() Loop // Insertar procesamiento de selección SelectionDetailRecords End of Loop;

El método "Execute" ejecuta la consulta, el método "Select" devuelve un valor del tipo "SelectionFromQueryResult". También puede utilizar el método Unload, que devuelve una tabla de valores.

Los parámetros de consulta se almacenan en la propiedad "Parámetros" (en este caso, es una estructura, por lo que aquí se aplican todos los métodos de la estructura: insertar, eliminar, etc.).

Un ejemplo de configuración del parámetro "Query.Parameters.Insert" ("Directorio", ReferenceReference). En la consulta, puede acceder a los parámetros a través del ampersand "&Reference". A continuación se muestra un ejemplo de solicitud utilizando parámetros:

Solicitud = Nueva Solicitud; Query.Text = "SELECT | Users.Reference AS Link, | Users.Parent AS Parent, | Users.Name AS Name |FROM | Directory.Users AS Users |WHERE | Users.Reference = &Directory"; Query.Parameters.Insert("Catálogo", DirectoryReference); Selección = Consulta.Ejecutar().Seleccionar(); Mientras Selection.Next() Loop // Insertar procesamiento de selección SelectionDetailRecords End of Loop;

Recuerde que el lenguaje de consulta está diseñado solo para leer datos de la base de datos, por lo que no tiene análogos de tales consultas. Sentencias SQL como INS ERT y UPDATE. Los datos sólo se pueden modificar a través de modelo de objeto lenguaje de programación incorporado 1C. Además, en el lenguaje de consulta 1C, hay operadores que no tienen análogos en SQL, por ejemplo:

  • EN LA JERARQUÍA
  • PONER
  • ÍNDICE POR

EN LA JERARQUÍA– le permite seleccionar todos los elementos del diccionario jerárquico que están incluidos en la jerarquía del enlace pasado. Solicitud de muestra usando EN LA JERARQUÍA:

SELECCIONE Productos.Enlace, Productos.Artículo DESDE Directorio.Productos COMO Productos DONDE Productos.Enlace EN JERARQUÍA(&Citrus)"

En este caso, todos los elementos subordinados del catálogo de nomenclatura de Citrus se devolverán al resultado, sin importar cuántos niveles de jerarquía tenga este catálogo.

Además, por ejemplo, la tarea es encontrar un producto con el nombre "Pen". El producto debe estar incluido en la jerarquía de “Papelería. Bienes”, es decir, no necesitamos buscar un picaporte. La estructura de la nomenclatura en este caso es la siguiente:

oficina

|_ Plumas estilográficas |_ Pluma roja |_ Pluma azul |_ Plumas de tinta |_ Reglas

accesorios

|_ Tiradores de puerta |_ Tirador de puerta simple |_ Tirador de puerta de lujo

Escribimos una consulta como esta:

SELECCIONE Mercancías.Enlace, Mercancías.Artículo DESDE Directorio.Mercancías COMO Mercancías DONDE Mercancías.Nombre Similar a "Pen%" Y Mercancías.Enlace EN JERARQUÍA(&Oficina)"

Al utilizar la estructura EN LA JERARQUÍA tenga en cuenta que si pasa una referencia vacía al parámetro "Oficina", la ejecución de la solicitud se ralentizará, ya que la plataforma verificará que cada elemento pertenezca a la raíz.

PONER– Esta declaración coloca el resultado en una tabla temporal. Ejemplo de solicitud:

SELECCIONAR Usuarios.Referencia AS Referencia, Usuarios.Padre AS Padre, Usuarios.Nombre AS Nombre PUT Usuarios seleccionados FROM Directorio.Usuarios AS Usuarios WHERE Usuarios.Referencia = &Directorio; SELECT SelectedUsers.Reference AS Link, SelectedUsers.Parent AS Parent, SelectedUsers.Name AS Name FROM SelectedUsers AS SelectedUsers

Esta consulta SQL será ejecutada por varias consultas:

  • Crear una tabla temporal (la plataforma puede "reutilizar" tablas temporales creadas previamente, por lo que la creación no siempre ocurre);
  • Poner datos en una tabla temporal;
  • Ejecución de la consulta principal, a saber, SEL ECT de esta tabla temporal;
  • Destrucción/limpieza de la mesa temporal.

Una tabla temporal se puede destruir explícitamente usando la construcción DESTRUIR, o implícitamente, al cerrar el administrador de tablas temporales.

El objeto "Solicitud" del lenguaje de programación integrado tiene la propiedad "TemporaryTable Manager", que está diseñada para trabajar con tablas temporales. Ejemplo de código:

MBT = NewTempTableManager(); Solicitud = Nueva Solicitud; Query.TemporaryTable Manager = MBT;

Después de ejecutar una consulta, la variable MBT se puede usar una segunda vez en otra consulta, lo que sin duda es otra ventaja de usar tablas temporales. En este caso, la tabla temporal se eliminará de la base de datos cuando se llame al método "Cerrar"...

MVT.Cerrar();

...o al borrar una variable de la memoria, es decir, al ejecutar el método en el que se declaró la variable. Las tablas temporales aumentan la carga en el subsistema del disco, por lo que no debe crear demasiados subsistemas temporales (en un bucle, por ejemplo) o subsistemas grandes.

ÍNDICE POR– este operador se usa junto con el operador PONER. Al crear una tabla temporal, este operador puede indexar la tabla creada, lo que acelera significativamente el trabajo con ella (pero solo si el índice coincide con su consulta).

Asesoramiento gratuito de expertos

¡Gracias por tus comentarios!

Un especialista de 1C se comunicará con usted en 15 minutos.

Características de algunos operadores de lenguaje de consulta

PARA CAMBIARoperador dado está diseñado para bloquear una tabla de consulta específica (o todas las tablas que participan en la consulta). El bloqueo se realiza colocando un candado en U sobre la mesa. En SQL, esto se implementa a través de la sugerencia UPDLOCK. Esta construcción es necesaria para evitar interbloqueos. Ejemplo de una consulta con una construcción PARA CAMBIAR:

SELECCIONE Usuarios.Referencia AS Enlace, Usuarios.Padre AS Padre, Usuarios.Nombre AS Nombre DESDE Directorio.Usuarios AS Usuarios

EN este ejemplo U El candado se colocará en la tabla "Usuarios". Si no especifica una tabla para bloquear, se impondrá a todas las tablas que participan en la consulta. Es importante señalar que esta construcción sólo funciona en configuraciones en las que el Modo automático gestión de bloqueos.



COMPUESTO- la consulta admite conexiones IZQUIERDA/DERECHA, COMPLETA, INTERIOR, que corresponde a combinaciones en SQL - UNIÓN IZQUIERDA/DERECHA, UNIÓN EXTERNA, UNIÓN INTERNA.

Sin embargo, al usar el generador de consultas, no podrá hacer UNIÓN DERECHA. El constructor simplemente intercambiará las tablas, pero el operador siempre quedará. Por esta razón, en 1C nunca encontrará el uso de una unión a la derecha.

Sintácticamente, la conexión se ve así:

SELECT Table1.Reference AS Reference FROM Reference.Reference1 AS Table1 LEFT JOIN Reference.Reference2 AS Table2 BY Table1.Attributes = Table2.Attributes

El lenguaje de consulta 1C no tiene un operador para unir el producto cartesiano (CROSS JOIN). Sin embargo, la ausencia de un operador no significa que el lenguaje de consulta no admita dicha unión. Puede unir tablas si es necesario de la siguiente manera:

SELECT Table1.Reference AS Reference FROM Reference.Reference1 AS Table1 LEFT JOIN Reference.Reference2 AS Table2 ON TRUE

Como puede ver en el ejemplo, la clave de conexión está configurada EN VERDAD, es decir, cada fila de una tabla corresponde a una fila de otra. El tipo de unión (IZQUIERDA, DERECHA, COMPLETA, INTERNA) no importa si tiene filas en ambas tablas, pero si ninguna de las tablas tiene filas (dejando ir la tabla), el resultado será diferente. Por ejemplo, al usar INTERNO El resultado de la conexión estará vacío. Utilizando IZQUIERDA DERECHA la unión generará o no datos dependiendo de si estamos uniendo una tabla con datos o no. Utilizando COMPLETO los datos de conexión siempre serán (naturalmente, solo una tabla, ya que la otra está vacía), la elección del tipo de conexión depende de la tarea específica de la aplicación.

Una pequeña pista visual de cómo funcionan. diferentes tipos conexiones:



ME GUSTA. A diferencia del operador similar lenguaje SQL– LIKE, plantilla para ME GUSTA se puede especificar usando solo algunos caracteres especiales:

  • % (porcentaje): una secuencia que contiene cualquier número de caracteres arbitrarios;
  • _ (guión bajo): un carácter arbitrario;
  • / - el siguiente carácter debe interpretarse como un carácter normal.

RESULTADOS EN el equivalente de SQL es el operador ROLLUP. Ejemplo de uso del operador RESULTADOS:

SELECCIONE Bienes.Precio COMO Precio, Bienes.Artículo COMO Bienes DE Directorio.Nomenclatura COMO Bienes RESULTADOS PROMEDIO(Precio) POR Bienes

El resultado será así:

Cama

9833,333

Planchar

Bolígrafo

Es decir, se agrega una línea adicional al resultado, que contiene el valor del campo por el cual se realiza la agrupación y el valor de la función de agregación.

Trabajar con solicitudes por lotes

1C le permite trabajar con lotes de solicitudes. En una solicitud por lotes, los textos de la solicitud están separados por un punto y coma (;). La ejecución de una solicitud por lotes 1C se lleva a cabo secuencialmente. Ejemplo de texto de solicitud de lote:

SELECCIONE Users.Link AS Link, Users.Parent AS Parent, Users.Name AS Name FROM Directory.Users AS Users;
SELECCIONE Programación de trabajo.Usuario AS Usuario, Programación de trabajo.Fecha COMO Fecha, Programación de trabajo Horas de trabajo AS Horas de trabajo DESDE Registro de datos Programación de trabajo COMO Programación de trabajo

Para obtener el resultado de todas las solicitudes incluidas en el paquete, debe utilizar el método del objeto de solicitud "ExecutePackage", en lugar de "Execute". Este método ejecuta todas las solicitudes secuencialmente. El resultado de la consulta es una matriz de resultados para cada consulta del paquete y el orden en la matriz es el mismo que el orden de las solicitudes en el cuerpo del paquete.

Teniendo en cuenta el lenguaje de consulta, vale la pena mencionar una característica como las tablas virtuales. Las tablas virtuales no están presentes en la base de datos; este es un tipo de contenedor que se ejecuta en el lado de DBMS como una consulta usando subconsultas. Un ejemplo de una consulta 1C usando tablas virtuales:

SELECT Registro de PasivosVolumen.Pasivo AS Obligación FROM Registro de Acumulación.Registro de Obligaciones.Volumen() AS Registro de ObligacionesVolumen

Tal consulta al DBMS se verá así:

SEL ECT T1.Fld25931RRef DE OM (SELECCIONE T2._Fld25931RRef COMO Fld25931RRef, CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8)) AS Fld25936Turnover_, CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8)) AS Fld25937Turnover_ FR OM dbo._AccumRgTn25938 T2 DONDE ((T2._Fld949 = @P1)) Y ((T2._Fld25936 @P2 O T2._Fld25937 @P3)) GRUPO POR T2._Fld25931RRef TENIENDO (CAST(SUM(T2._Fld25936) ) ) COMO NUMÉRICO(38, 8))) 0.0 O (CAST(SUM(T2._Fld25937) COMO NUMÉRICO(38, 8))) 0.0) T1>>>>

Se puede ver que no se parece a SQL, ya que hay una subconsulta, una agrupación. Las tablas virtuales, en general, son “azúcar sintáctico”, es decir, fueron creadas, en general, para la conveniencia de desarrollar consultas, para que las consultas sean más compactas y más legibles.

Solo los registros tienen tablas virtuales, pero las tablas virtuales que están disponibles para un registro se pueden ver en el generador de consultas.



Al usar tablas virtuales, siempre debe dar una condición de selección. De lo contrario, pueden ocurrir problemas de rendimiento.



En el cuerpo de la solicitud se ve así:

Acumulación Registro.RegistroPasivos.Facturación(, Operación = &Operación) AS RegistroObligacionesFacturación

Para la conveniencia de escribir consultas, es decir, crear textos de consulta, hay un constructor en 1C que se puede llamar a través del menú contextual (clic con el botón derecho):



En Query Builder, puede ver una lista completa de funciones y operadores de lenguaje de consulta admitidos.


Query Builder es una herramienta visual muy flexible para crear consultas de cualquier complejidad. Sólo está disponible en el modo configurador. En el modo Enterprise, hay una llamada "Consola de consulta" - esto es procesamiento externo suministrado en el disco ITS. Para una aplicación administrada, la consola de solicitud se puede descargar desde el sitio web its.1c.ru.

La descripción del trabajo en el generador de consultas está más allá del alcance de este artículo, por lo que no se considerará en detalle.

Motivos del rendimiento de consulta subóptimo

A continuación se muestra una lista de las razones principales (pero no todas) que provocan una ejecución lenta de las consultas.

  • Uso de join con subconsultas

No se recomienda unir con subconsultas, las subconsultas deben reemplazarse con tablas temporales. Unir subconsultas puede provocar una pérdida significativa de rendimiento, mientras que la ejecución de una consulta en diferentes DBMS puede variar significativamente en velocidad. La velocidad de ejecución de tales consultas también es sensible a las estadísticas en el DBMS. El motivo de este comportamiento es que el optimizador de DBMS no siempre puede determinar correctamente el plan óptimo de ejecución de consultas, ya que el optimizador no sabe nada acerca de cuántas filas devolverá la subconsulta después de su ejecución.

  • Uso de tablas virtuales en uniones de consulta

Las tablas virtuales a nivel DBMS se ejecutan como subconsultas, por lo que las razones son las mismas que en el primer párrafo.

  • Uso de condiciones en una consulta que no coinciden con los índices existentes

Si en las condiciones de consulta (en el operador DONDE o en condiciones de mesa virtual) usa campos que no están todos incluidos en el índice, solicitud dada se hará con usando SQL Construcciones de escaneo de tabla o escaneo de índice (en su totalidad o en parte). Esto afectará no solo el tiempo de ejecución de la consulta, sino que también se impondrá un bloqueo S excesivo en las filas adicionales, lo que a su vez puede provocar un aumento del bloqueo, es decir, se bloqueará toda la tabla.

  • Uso de OR en condiciones de consulta

Uso operador lógico O En construcción DONDE también puede resultar en una exploración de la tabla. Esto se debe al hecho de que el DBMS no puede usar el índice correctamente. En lugar de O Se puede aplicar la construcción COMBINA TODO.

  • Obtener datos a través de un punto para campos de tipo compuesto

No se recomienda recibir valores a través de un punto (en la construcción ELIGE DONDE), porque si el atributo del objeto es un tipo compuesto, la combinación se producirá con cada tabla incluida en este tipo compuesto. Como resultado, la consulta al DBMS será significativamente más complicada, lo que puede impedir que el optimizador elija el plan de ejecución de consulta correcto.



¿Te gustó el artículo? Compártelo