Esecuzione di query batch in 1 secondo. Richieste batch di manichini. Metodi Run() e RunBatch()

Questo articolo è destinato ai lettori che hanno familiarità con il linguaggio SQL.

Il linguaggio di query 1C, utilizzato dalla versione 8, oggi è diventato uno strumento utile per lavorare con i database, che consente di leggere da essi, ma non di scrivere. Dal punto di vista sintattico il linguaggio delle query è molto simile al linguaggio SQL, ma in russo.

Di seguito è riportata una tabella di corrispondenza tra i principali linguaggi di query e gli operatori SQL:

Operatori del linguaggio di query 1C

Istruzione SQL

VARIE

COMPOSTO

RAGGRUPPA PER

COMBINA

ORDINA PER

E questo non è un elenco completo. Informazioni di riferimento più complete sugli operatori del linguaggio di query disponibili possono essere ottenute in Progettazione query, che verrà discussa di seguito.

L'esecuzione di una richiesta 1C dal codice del programma viene eseguita utilizzando l'oggetto linguistico integrato "Richiesta". Un esempio di scrittura di una query sul database utilizzando il linguaggio di programmazione integrato:

Richiesta = Nuova richiesta; Query.Text = "SELEZIONA | Sinonimo.Link AS Link |FROM | Directory.Directory1 AS Sinonimo"; Seleziona = Query.Esegui().Select(); While Selection.Next() Loop // Inserisci l'elaborazione della selezione SelectionDetailedRecords EndCycle;

Il metodo “Run” esegue la query, il metodo “Select” restituisce un valore di tipo “SelectFromQueryResult”. È inoltre possibile utilizzare il metodo Unload, che restituisce una tabella di valori.

I parametri della richiesta sono memorizzati nella proprietà "Parametri" (in questo caso, questa è una struttura, quindi tutti i metodi della struttura sono applicabili qui: inserisci, elimina, ecc.).

Un esempio di impostazione del parametro “Query.Parameters.Insert” (“Directory”, DirectoryLink). Nella richiesta è possibile accedere ai parametri utilizzando la e commerciale “&Directory”. Di seguito è riportato un esempio di richiesta che utilizza parametri:

Richiesta = Nuova richiesta; Query.Text = "SELECT | Users.Link AS Link, | Users.Parent AS Parent, | Users.Name AS Nome |FROM | Directory.Users AS Users |WHERE | Users.Link = &Directory"; Query.Parameters.Insert("Directory", DirectoryLink); Seleziona = Query.Esegui().Select(); While Selection.Next() Loop // Inserisci l'elaborazione della selezione SelectionDetailedRecords EndCycle;

Ricordiamo che il linguaggio di query è destinato solo alla lettura dei dati dal database, quindi non ha analoghi di istruzioni SQL come INS ERT e UPDATE. I dati possono essere modificati solo tramite il modello a oggetti del linguaggio di programmazione 1C integrato. Anche nel linguaggio di query 1C ci sono operatori che non hanno analoghi in SQL, ad esempio:

  • NELLA GERARCHIA
  • POSTO
  • INDICE PER

NELLA GERARCHIA– consente di selezionare tutti gli elementi della directory gerarchica che sono inclusi nella gerarchia del collegamento trasferito. Richiesta di esempio utilizzando NELLA GERARCHIA:

SELEZIONA Prodotti.Link, Prodotti.Articolo FROM Directory.Prodotti AS Prodotti WHERE Prodotti.Link IN GERARCHIA(&Citrus)"

In questo caso, il risultato restituirà tutti gli elementi subordinati della directory della nomenclatura Citrus, indipendentemente dal numero di livelli gerarchici di questa directory.

Inoltre, ad esempio, il compito è trovare un prodotto con il nome "Penna". Il prodotto deve essere incluso nella gerarchia “Cancelleria”. Merci”, cioè non dobbiamo cercare la maniglia della porta. La struttura della nomenclatura in questo caso è la seguente:

Ufficio

|_ Penne stilografiche |_ Penna rossa |_ Penna blu |_ Penne a inchiostro |_ Righelli

Accessori

|_ Maniglie per porte |_ Maniglia per porte semplice |_ Maniglia per porte di lusso

Scriviamo la seguente richiesta:

SELEZIONA Prodotti.Link, Prodotti.Articolo FROM Directory.Prodotti AS Prodotti WHERE Prodotti.Nome Come "Penna%" AND Prodotti.Link IN GERARCHIA(&Cancelleria)"

Quando si utilizza il disegno NELLA GERARCHIAè necessario tenere conto che se si passa un collegamento vuoto al parametro “Office”, l'esecuzione della richiesta rallenterà, poiché la piattaforma controllerà ogni elemento per vedere se appartiene alla radice.

POSTO– Questa istruzione inserisce il risultato in una tabella temporanea. Richiesta di esempio:

SELECT Users.Link AS Link, Users.Parent AS Parent, Users.Name AS Nome PLACE SelectedUsers FROM Directory.Users AS Users WHERE Users.Link = &Directory; SELECT SelectedUsers.Link AS Link, SelectedUsers.Parent AS Parent, SelectedUsers.Name AS Nome FROM SelectedUsers AS SelectedUsers

Questa query SQL verrà eseguita da diverse query:

  • Creazione di una tabella temporanea (la piattaforma può “riutilizzare” tabelle temporanee precedentemente create, quindi non sempre la creazione avviene);
  • Inserimento dei dati in una tabella temporanea;
  • Eseguendo la query principale, ovvero SEL ECT da questa tabella temporanea;
  • Distruggere/pulire una tabella temporanea.

Una tabella temporanea può essere distrutta esplicitamente, tramite il costrutto DISTRUGGERE o implicitamente - quando si chiude il gestore tabelle temporaneo.

L'oggetto "Query" del linguaggio di programmazione integrato ha una proprietà "Gestore tabelle temporanee", progettata per lavorare con tabelle temporanee. Codice di esempio:

MVT = Nuovo TemporaryTableManager(); Richiesta = Nuova richiesta; Query.TemporaryTableManager = MVT;

Dopo aver eseguito una query, la variabile MVT può essere utilizzata una seconda volta in un'altra query, il che rappresenta senza dubbio un altro vantaggio dell'utilizzo delle tabelle temporanee. In questo caso, la tabella temporanea dal database verrà eliminata quando verrà chiamato il metodo “Close”...

MVT.Chiudi();

...o quando si cancella una variabile dalla memoria, cioè quando si esegue il metodo in cui è stata dichiarata la variabile. Le tabelle temporanee aumentano il carico sul sottosistema del disco, quindi non dovresti creare troppi sottosistemi temporanei (in un ciclo, ad esempio) o sottosistemi di grandi volumi.

INDICE PER– questo operatore viene utilizzato insieme all'operatore POSTO. Quando si crea una tabella temporanea, questo operatore può indicizzare la tabella creata, il che accelera notevolmente il lavoro con essa (ma solo se l'indice corrisponde alla query).

Consulenza gratuita di esperti

Grazie per la vostra richiesta!

Uno specialista 1C ti contatterà entro 15 minuti.

Funzionalità di alcuni operatori del linguaggio di query

PER CAMBIARE– questo operatore ha lo scopo di bloccare una tabella di query specifica (o tutte le tabelle che partecipano alla query). Il bloccaggio si ottiene applicando un blocco a U al tavolo. In SQL questo viene implementato tramite il suggerimento UPDLOCK. Questa progettazione è necessaria per prevenire situazioni di stallo. Esempio di richiesta con costruzione PER CAMBIARE:

SELEZIONA Utenti.Link AS Link, Utenti.Parent AS Parent, Utenti.Nome AS Nome DA Directory.Users AS Utenti SINISTRA ISCRIVITI Directory.RFK AS RFK DA Utenti.RFK = RFK.Link PER CAMBIARE Directory.Users

In questo esempio, il blocco U verrà inserito nella tabella Utenti. Se non si specifica una tabella per un blocco, questo verrà imposto a tutte le tabelle che partecipano alla query. È importante notare che questo design funziona solo nelle configurazioni in cui è abilitata la modalità di gestione automatica dei blocchi.



COMPOSTO– la richiesta supporta le connessioni SINISTRA/DESTRA, COMPLETA, INTERNA, che corrisponde ai join in SQL – LEFT/RIGHT JOIN, OUTER JOIN, INNER JOIN.

Tuttavia, quando utilizzi il generatore di query non sarai in grado di farlo ISCRIVITI GIUSTO. Il costruttore scambierà semplicemente le tabelle, ma l'operatore sarà sempre mancino. Per questo motivo non vedrai mai l'uso del right join in 1C.

Sintatticamente la connessione si presenta così:

SELEZIONA Table1.Link AS Link DA Directory.Directory1 AS Table1 LEFT JOIN Directory.Directory2 AS Table2 BY Table1.Attributes = Table2.Attributes

Il linguaggio di query 1C non dispone di un operatore per l'unione di un prodotto cartesiano (CROSS JOIN). Tuttavia, l'assenza di un operatore non significa che il linguaggio di interrogazione non supporti tale connessione. Se necessario, puoi unire tabelle come questa:

SELEZIONA Table1.Link AS Link DA Directory.Directory1 AS Table1 LEFT JOIN Directory.Directory2 AS Table2 BY TRUE

Come si può vedere dall'esempio, la chiave di connessione è impostata PER VERO, ovvero ogni riga di una tabella corrisponde a una riga di un'altra. Il tipo di join (LEFT, RIGHT, FULL, INNER) non è importante se sono presenti righe in entrambe le tabelle, ma se non ci sono righe in una delle tabelle (diciamo la tabella), il risultato sarà diverso. Ad esempio, quando si utilizza INTERNO il risultato della connessione sarà vuoto. Utilizzando SINISTRA DESTRA il risultato dell'unione sarà o meno costituito da dati a seconda della tabella a cui ci stiamo unendo, con o meno dati. Utilizzando PIENO I dati verranno sempre collegati (naturalmente solo da una tabella, poiché l'altra è vuota); la scelta del tipo di connessione dipende dal compito specifico dell'applicazione.

Un piccolo suggerimento visivo su come funzionano i diversi tipi di connessione:



COME. A differenza dell'operatore SQL simile - LIKE, il modello per COME può essere specificato utilizzando solo alcuni caratteri speciali:

  • % (percentuale): una sequenza contenente un numero qualsiasi di caratteri arbitrari;
  • _ (trattino basso): un carattere arbitrario;
  • / - il carattere successivo deve essere interpretato come un carattere normale.

RISULTATI DEL SOFTWARE L'analogo SQL è l'operatore ROLLUP. Esempio di utilizzo dell'operatore RISULTATI:

SELEZIONA Prodotti.Prezzo AS Prezzo, Prodotti.Prodotto AS Prodotto DA Directory.Nomenclatura AS Prodotti RISULTATI MEDIA (Prezzo) PER Prodotto

Il risultato sarà così:

Letto

9833,333

Ferro

Penna

Cioè, al risultato viene aggiunta una riga aggiuntiva contenente il valore del campo in base al quale viene eseguito il raggruppamento e il valore della funzione di aggregazione.

Lavorare con richieste batch

1C ti consente di lavorare con batch di richieste. In una richiesta batch, i testi della richiesta sono separati da punto e virgola (;). Una richiesta batch 1C viene eseguita in sequenza. Esempio di testo della richiesta batch:

SELEZIONARE Utenti.Link AS Link, Users.Parent AS Parent, Users.Name AS Nome FROM Directory.Users AS Users;
SELEZIONA Programma di lavoro.Utente AS Utente, Programma di lavoro.Data COME Data, Programma di lavoro.Ore di lavoro COME Orario di lavoro DA Informazioni registro.Programma di lavoro AS Programma di lavoro

Per ottenere il risultato di tutte le query incluse in un pacchetto, è necessario utilizzare il metodo “ExecutePackage” dell'oggetto richiesta, anziché “Esegui”. Questo metodo esegue tutte le richieste in sequenza. Il risultato della query è un array di risultati per ogni query nel pacchetto e la sequenza di posizionamento nell'array è la stessa della sequenza di query nel testo del pacchetto.

Quando si considera un linguaggio di query, vale la pena menzionare una funzionalità come le tabelle virtuali. Le tabelle virtuali non sono presenti nel database; sono una sorta di wrapper che viene eseguito sul lato DBMS come query utilizzando sottoquery. Esempio di query 1C utilizzando tabelle virtuali:

SELEZIONARE RegisterLiabilitiesTurnovers.Liability AS Responsabilità FROM RegisterAccumulations.RegisterLiabilities.Turnovers() AS RegisterLiabilitiesTurnovers

Tale query al DBMS sarà simile alla seguente:

SEL ECT T1.Fld25931RRef FR OM (SELECT T2._Fld25931RRef AS Fld25931RRef, CAST(SUM(T2._Fld25936) AS NUMERIC(38, 8)) AS Fld25936Fatturato_, CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8) ) AS Fld25937Turnover_ FR OM dbo._AccumRgTn25938 T2 WH ERE ((T2._Fld949 = @P1)) AND ((T2._Fld25936 @P2 OR T2._Fld25937 @P3)) GRUPPO PER T2._Fld25931RRef HAVING (CAST(SUM(T2._Fld2 ) 5936 ) AS NUMERIC(38, 8))) 0.0 OR (CAST(SUM(T2._Fld25937) AS NUMERIC(38, 8))) 0.0) T1>>>>

Si può vedere che non assomiglia a SQL, poiché esiste una sottoquery, raggruppamento. Le tabelle virtuali, in generale, sono "zucchero sintattico", ovvero vengono create, in generale, per comodità di sviluppo di query, in modo che le query siano più compatte e più leggibili.

Solo i registri hanno tabelle virtuali, ma nel Designer query è possibile vedere quali tabelle virtuali sono disponibili in un registro.



Quando si utilizzano tabelle virtuali, è necessario fornire sempre una condizione di selezione. In caso contrario, potrebbero verificarsi problemi di prestazioni.



Nel corpo della richiesta appare così:

Registro di accumulazione. Registro delle passività (, Operazione = &Operazione) AS Registro delle passività

Per comodità di scrivere query, ovvero creare testi di query, in 1C è presente un costruttore che può essere richiamato tramite il menu contestuale (tasto destro del mouse):



Nella finestra di progettazione query è possibile visualizzare un elenco completo delle funzioni e degli operatori del linguaggio di query supportati.


Il Query Builder è uno strumento visivo molto flessibile per creare query di qualsiasi complessità. È disponibile solo in modalità configuratore. In modalità Enterprise è presente la cosiddetta "Query Console": si tratta di un'elaborazione esterna fornita sul disco ITS. Per un'applicazione gestita, la console delle query può essere scaricata da its.1c.ru.

Una descrizione del funzionamento in Progettazione query va oltre lo scopo di questo articolo e pertanto non verrà discussa in dettaglio.

Motivi per prestazioni delle query non ottimali

Di seguito è riportato un elenco dei motivi principali (ma non tutti) che portano a un rallentamento dell'esecuzione delle query.

  • Utilizzo dei join con sottoquery

Non è consigliabile eseguire un join con sottoquery; le sottoquery dovrebbero essere sostituite con tabelle temporanee. La concatenazione delle sottoquery può portare a perdite significative di prestazioni e l'esecuzione delle query su DBMS diversi può variare in modo significativo in termini di velocità. La velocità di esecuzione di tali query dipende anche dalle statistiche nel DBMS. Il motivo di questo comportamento è che l'ottimizzatore DBMS non è sempre in grado di determinare correttamente il piano di esecuzione ottimale della query, poiché non sa nulla su quante righe restituirà la sottoquery dopo l'esecuzione.

  • Utilizzo di tabelle virtuali nei join di query

Le tabelle virtuali a livello DBMS vengono eseguite come sottoquery, quindi le ragioni sono le stesse del primo paragrafo.

  • Utilizzo di condizioni in una query che non si adattano agli indici esistenti

Se nelle condizioni di richiesta (nell'operator DOVE o condizioni di tabella virtuale) utilizza campi che non sono tutti inclusi nell'indice, questa query verrà eseguita utilizzando la scansione della tabella del costrutto SQL o la scansione dell'indice (interamente o in parte). Ciò influirà non solo sul tempo di esecuzione della query, ma anche su righe aggiuntive verrà applicato un blocco S eccessivo, che a sua volta può portare a un'escalation dei blocchi, ovvero all'intera tabella verrà bloccata.

  • Utilizzo di OR nelle condizioni di query

Utilizzando l'operatore logico O nella progettazione DOVE potrebbe anche comportare una scansione della tabella. Ciò accade perché il DBMS non può utilizzare correttamente l'indice. Invece di O puoi usare il disegno COMBINA TUTTO.

  • Ricezione di dati tramite un punto per campi di tipo composito

Si sconsiglia di ottenere valori tramite punto (nella costruzione SCEGLI DOVE), perché se l'attributo dell'oggetto risulta essere un tipo complesso, l'unione avverrà con ogni tabella inclusa in questo tipo complesso. Di conseguenza, la query DBMS sarà notevolmente più complicata, il che potrebbe impedire all'ottimizzatore di scegliere il piano di esecuzione della query corretto.

La piattaforma 1C Enterprise consente di eseguire più query in sequenza alla volta. In 1C questo è chiamato pacchetto di richiesta. All'interno di un pacchetto, ogni richiesta è separata da un punto e virgola.

Per ottenere l'esecuzione passo passo delle query in un pacchetto, di norma, vengono inizialmente create tabelle temporanee, quindi vengono formate le condizioni per la loro condivisione, come filtri, join e join. Grazie a ciò si ottiene il risultato finale. Le tabelle temporanee ottenute come risultato di qualsiasi query in un batch continuano ad esistere fino alla fine del batch nel suo insieme o finché non viene eseguita una query che distrugge le tabelle temporanee.

Inoltre, l'utilizzo di query batch e tabelle temporanee aumenta notevolmente la leggibilità dell'intero segmento di questo codice. Le query complesse che contengono anche query nidificate possono essere molto difficili da comprendere. Tuttavia, se si suddivide una query lunga e complessa in più query e si utilizzano anche tabelle temporanee, ciò non solo migliorerà la percezione, ma nella maggior parte dei casi porterà a un aumento delle prestazioni.

Un altro dettaglio importante a favore delle query batch in 1C è che, diversamente, possiamo ottenere separatamente il risultato di ciascuna query nel batch.

Un esempio di creazione di un pacchetto di richieste in linguaggio 1C

Per vedere un esempio di come creare un pacchetto di query, utilizzeremo il query designer, che chiameremo per chiarezza dalla query console. Pertanto, possiamo vedere immediatamente il risultato dell'esecuzione del pacchetto.

Creiamo una semplice richiesta batch. Suggerisco di inserire subito il testo della richiesta in , per poi aprirlo e vedere come si forma il pacchetto di richieste. Aggiungi una nuova richiesta alla console e incolla il seguente testo:

Ottieni 267 lezioni video su 1C gratuitamente:

Collegamento autoportante,
Autosufficiente.Genitore,
Codice autoportante,
Autoportante Codice di selezione rapida,
Nome autoportante.
Autoportante.Tipo,
Autoportante. Fuori bilancio,
Autoportante.
DA
Piano dei conti Autoportante AS Autoportante
DOVE
Autoportante.Link = &Account
;
////////////////////////////////////////////////////////////////////////////////

SCEGLIERE
Tipi autoportantiSubconto.Numero linea Numero linea AS,
AutoportanteTipi di Subconto.ViewSubconto AS TypeSubconto,
Self-supportingTypesSubconto.TypeSubconto.Name Nome AS,
Self-supportingTypesSubconto.TypeSubconto.ValueType ASValueType,
Self-supportingTypesSubconto.OnlyTurnover AS OnlyTurnover,
Self-supportingTypesSubconto.Summary AS Sommativa
DA
Piano dei conti Autoportante. Tipologie di Sottoconto AS Autocontabilità
DOVE
Self-supportingTypesSubaccount.Link = &Account
ORDINA PER
TypesSubconto.NumberLines autoportante

Per me assomiglia a questo:

Passiamo ora al progettista query. Qui saremo interessati alla scheda “Richiedi pacchetto”:

Come puoi vedere, abbiamo un pacchetto di due richieste. Facendo doppio clic su uno qualsiasi di essi, è possibile procedere alla modifica:

Fare clic sul pulsante "Ok" e provare a vedere il risultato della richiesta batch.

Impostiamo il parametro "Account". È possibile selezionare qualsiasi conto dal piano dei conti. Come probabilmente hai già intuito, questo pacchetto di richieste dovrebbe ricevere le proprietà dell'account. Fare clic su "Esegui" e vedere il risultato:

Metodi Run() e RunBatch()

Blog aziendale di 1C GOODWILL

La piattaforma 1C Enterprise consente di eseguire più query in sequenza alla volta. In 1C questo è chiamato pacchetto di richiesta. All'interno di un pacchetto, ogni richiesta è separata da un punto e virgola.

Per ottenere l'esecuzione passo passo delle query in un pacchetto, di norma, vengono inizialmente create tabelle temporanee, quindi vengono formate le condizioni per la loro condivisione, come filtri, join e join. Grazie a ciò si ottiene il risultato finale. Le tabelle temporanee ottenute come risultato di qualsiasi query in un batch continuano a esistere fino alla fine del batch nel suo insieme o finché non viene eseguita una query che distrugge le tabelle temporanee.

Inoltre, l'utilizzo di query batch e tabelle temporanee aumenta notevolmente la leggibilità dell'intero segmento di questo codice. Le query complesse che contengono anche query nidificate possono essere molto difficili da comprendere. Tuttavia, se si suddivide una query lunga e complessa in più query e si utilizzano anche tabelle temporanee, ciò non solo migliorerà la percezione, ma nella maggior parte dei casi porterà a un aumento delle prestazioni.

Un altro dettaglio importante a favore delle query batch in 1C è che, a differenza delle query annidate, possiamo ottenere separatamente il risultato di ciascuna query nel batch.

Un esempio di creazione di un pacchetto di richieste in linguaggio 1C

Per vedere un esempio di come creare un pacchetto di query, utilizzeremo il query designer, che chiameremo, per chiarezza, dalla query console. Pertanto, possiamo vedere immediatamente il risultato dell'esecuzione del pacchetto.

Creiamo una semplice richiesta batch. Suggerisco di incollare immediatamente il testo della richiesta nella console, quindi di aprire il costruttore e vedere come viene formato il pacchetto di richiesta. Aggiungi una nuova richiesta alla console e incolla il seguente testo:

Autosufficiente.Genitore,

Codice autoportante,

Autoportante Codice di selezione rapida,

Nome autoportante,

Autoportante.Tipo,

Autoportante. Fuori bilancio,

Autoportante.

Piano dei conti Autoportante AS Autoportante

////////////////////////////////////////////////////////////////////////////////

Tipi autoportantiSubconto.Numero linea Numero linea AS,

AutoportanteTipi di Subconto.ViewSubconto AS TypeSubconto,

Self-supportingTypesSubconto.TypeSubconto.Name Nome AS,

Self-supportingTypesSubconto.TypeSubconto.ValueType ASValueType,

Self-supportingTypesSubconto.OnlyTurnover AS OnlyTurnover,

Self-supportingTypesSubconto.Summary AS Sommativa

Piano dei conti Autoportante. Tipologie di Sottoconto AS Autocontabilità

ORDINA PER

TypesSubconto.NumberLines autoportante

Per me assomiglia a questo:

Passiamo ora al progettista query. Qui saremo interessati alla scheda “Richiedi pacchetto”:

Come puoi vedere, abbiamo un pacchetto di due richieste. Facendo doppio clic su uno qualsiasi di essi, è possibile procedere alla modifica:

Fare clic sul pulsante "Ok" e provare a vedere il risultato della richiesta batch.

Impostiamo il parametro "Account". È possibile selezionare qualsiasi conto dal piano dei conti. Come probabilmente hai già intuito, questo pacchetto di richieste deve ricevere le proprietà dell'account. Fare clic su "Esegui" e vedere il risultato:

Metodi Run() e RunBatch()

Oltre al metodo Execute(), che eseguirà una per una tutte le richieste in batch e restituirà il risultato dell'ultima richiesta, in 1C esiste un metodo ExecuteBatch(). Restituisce una serie di campioni di ciascuna richiesta nel batch. Nell'esempio sopra, viene eseguito questo metodo.

ArrayResults = Query.ExecuteBatch();

Selezione1 = ArrayResults.Select();

Se Select1.Next() Allora

//Azioni con selezione 1

finisci se;

SelectionViewsSubconto = ArrayResults.Select();

Il post Lavorare con le richieste batch in 1C 8.3 e 8.2 è apparso per la prima volta sul blog aziendale 1C GOODWILL.

aumentano notevolmente la leggibilità, il che riduce la probabilità di errori => solo questo mi basta.

Il linguaggio di query integrato di 1C:Enterprise versione 8.0 non aveva la possibilità di utilizzare tabelle temporanee e scrivere query batch. Allo stesso tempo, spesso era necessario eseguire calcoli complessi all'interno di un'unica richiesta (ovvero un ciclo di interazione tra client - server 1C:Enterprise - server DBMS). Per risolvere tali problemi, sono state utilizzate le sottoquery: chiamate non a oggetti di metadati, ma a selezioni da questi oggetti. In genere, le sottoquery venivano eseguite con il raggruppamento e spesso venivano utilizzate nei join.

L'ottimizzatore del server DBMS (indipendentemente dal DBMS utilizzato) non è sempre in grado di ottimizzare correttamente tale query. In questo caso, il problema per l'ottimizzatore è scegliere il metodo di connessione giusto. Esistono diversi algoritmi per unire due campioni. La scelta dell'uno o dell'altro algoritmo dipende da quanti record saranno contenuti nell'uno e nell'altro campione. Se stai unendo due tabelle fisiche, il DBMS può facilmente determinare la dimensione di entrambi i campioni in base alle statistiche disponibili. Se una delle selezioni unite è una sottoquery, diventa molto difficile capire quanti record restituirà. In questo caso, il DBMS potrebbe commettere un errore nella scelta del piano, il che porterà a un calo catastrofico delle prestazioni delle query.

La riscrittura della query utilizzando il metodo precedente ha lo scopo di semplificare il lavoro dell'ottimizzatore DBMS. Nella query riscritta, tutte le selezioni che partecipano ai join saranno tabelle fisiche e il DBMS sarà in grado di determinare facilmente la dimensione di ciascuna selezione. Ciò consentirà al DBMS di garantire la selezione del piano più veloce tra tutti i possibili. Inoltre, il DBMS farà la scelta giusta indipendentemente da qualsiasi condizione. Una query riscritta in questo modo funzionerà altrettanto bene su qualsiasi DBMS, il che è particolarmente importante quando si sviluppano soluzioni di circolazione. Inoltre, una query riscritta in questo modo risulta più leggibile, più facile da comprendere e da eseguire il debug.

Dovrebbe essere chiaro che riscrivendo la query in questo modo, potremmo aver introdotto un rallentamento a causa di un sovraccarico aggiuntivo: la creazione di tabelle temporanee. Se il DBMS non commette errori nella scelta del piano, probabilmente eseguirà la vecchia query più velocemente di quella nuova. Tuttavia, questo rallentamento sarà sempre estremamente contenuto. L'entità del rallentamento dipende dal DBMS utilizzato e dalle prestazioni dell'hardware. In un caso tipico, possono essere necessari diversi millisecondi per creare una tabella temporanea. Cioè, questi rallentamenti non possono avere un impatto notevole sulle prestazioni del sistema e, di norma, possono essere ignorati.