FirebirdSQL logo

OPTIMIZE FOR

Affectation

Changer la stratégie de l’optimiseur.

Синтаксис
SELECT ...
FROM [...]
[WHERE ...]
[...]
[OPTIMIZE FOR {FIRST | ALL} ROWS]

La clause OPTIMIZE FOR vous permet de changer la stratégie de l’optimiseur au niveau de la requête SQL courante.Elle ne peut apparaître que dans l’instruction SELECT de la requête SQL de niveau supérieur.

Il existe deux stratégies d’optimisation des requêtes :

  • FIRST ROWS - l’optimiseur construit le plan de requête pour ne récupérer que les premières lignes de la requête de la manière la plus rapide ;

  • ALL ROWS - l’optimiseur construit le plan de requête pour récupérer toutes les lignes de la requête le plus rapidement possible.

Dans la plupart des cas, une stratégie d’optimisation ALL ROWS' est nécessaire. Cependant, si vous avez des applications avec des grilles de données,dans lesquelles seules les premières lignes du résultat sont affichées et les autres sont récupérées en fonction des besoins, la stratégie `FIRST ROWS peut être préférable car elle réduit le temps de déconnexion.

Par défaut, la stratégie d’optimisation spécifiée dans le paramètre OptimizeForFirstRows du fichier de configuration est utiliséefirebird.conf ou database.conf. OptimiseForFirstRows = false correspond à la stratégie ALL ROWS,OptimiseForFirstRows = true correspond à la stratégie First ROWS.

La stratégie d’optimisation peut également être modifiée au niveau de la session à l’aide de l’opérateur SET OPTIMIZE.La clause OPTIMIZE FOR spécifiée dans l’instruction SQL vous permet de remplacer la stratégie spécifiée au niveau de la session.

La clause OPTIMIZE FOR spécifie toujours la clause OPTIMIZE FOR la plus récente dans une requête SELECT, mais avant la clause INTO.

Note

Si la requête SELECT contient FIRST …​ SKIP, ROWS, OFFSET …​ FETCH, l’optimiseur passe implicitement au mode FIRST ROWS.

INTO

affectation

Transférer les résultats de SELECT dans des variables.

Disponible en:

PSQL

Syntaxe:
SELECT [...] <column-list>
FROM ...
[...]
[INTO <variable-list>]

<variable-list> ::= [:]psqlvar [, [:]psqlvar ...]

En PSQL (procédures stockées, triggers, etc.) les résultats d’une commande SELECT peuvent être chargés ligne par ligne dans des variables locales (le nombre, l’ordre et les types de variables locales doivent correspondre aux champs SELECT). Souvent, un tel chargement est le seul moyen de faire quelque chose avec les valeurs de retour.

L’instruction SELECT simple ne peut être utilisé dans PSQL que s’il ne retourne pas plus d’une chaîne de caractères, c’est-à-dire s’il s’agit d’une requête unique. Pour les requêtes qui retournent plusieurs chaînes de caractères, PSQL suggère d’utiliser l’instruction FOR SELECT.

Important

Lorsque la requête ne renvoie aucune donnée (zéro ligne), les valeurs des variables de la liste INTO ne sont pas modifiées.

De plus, PSQL prend en charge l’instruction DECLARE CURSOR, qui associe un curseur nommé à une commande SELECT particulière — et ce curseur peut alors être utilisé pour naviguer dans l’ensemble de données retourné.

En PSQL, la clause INTO doit apparaître à la toute fin de la commande SELECT.

Important
Veuillez noter.

En PSQL, les deux points avant les noms de variables sont facultatifs.

Exemples

Dans PSQL, vous pouvez attribuer les valeurs de min_amt, avg_amt et max_amt à des variables prédéfinies ou à des paramètres de sortie :

SELECT
  MIN(amount),
  AVG(CAST(amount AS float)),
  MAX(amount)
FROM orders
WHERE artno = 372218
INTO min_amt,
     avg_amt,
     max_amt;

Dans cette requête, CAST est utilisé pour calculer correctement la valeur moyenne. Si la valeur n’est pas convertie en float, la valeur moyenne sera tronquée à la valeur entière la plus proche.

Dans le déclencheur :

SELECT LIST(name, ', ')
FROM persons p
WHERE p.id IN (new.father, new.mother)
INTO new.parentnames;

expressions de table courantes CTE ("WITH …​ AS …​ SELECT")

expressions de table courantes (Common Table Expressions), en abrégé CTE, sont décrites comme des tables ou des vues virtuelles définies dans le préambule de la requête principale, qui participent à la requête principale. La requête principale peut faire référence à n’importe quelle CTE définie dans le préambule, comme lors de l’extraction de données de tables ou de vues ordinaires. Les CTE peuvent être récursives, c’est-à-dire se référer à elles-mêmes, mais ne peuvent pas être imbriquées.

Syntaxe
<query-expression> ::=
  [<with-clause>]
  <query-expression-body>
  [<order-by-clause>]
  [   <rows-clause>
    | { [<result-offset-clause>] [<fetch-first-clause>] }]

<with-clause> ::=
  WITH [RECURSIVE] <cte> [, <cte> ...]

<cte> ::=
  query-name [(<column-name-list>)] AS (<query-expression>)

<column-name-list> ::= column-name [, column-name ...]
Table 1. Paramètres CTE
Paramètre Description

query-name

Le nom de l’expression du tableau.

column-name

Un alias (alias) pour une colonne d’une expression de tableau.

Notes
  • Une définition CTE peut contenir n’importe quel instruction SELECT valide tant qu’elle ne contient pas le préambule “`WITH…​`” (les instructions WITH ne peuvent pas être imbriqués) ;

  • Les CTE peuvent s’utiliser mutuellement, mais les références ne doivent pas comporter de boucles ;

  • CTE peut être utilisé dans n’importe quelle partie de la requête principale ou autre expression tabulaire et autant de fois que souhaité ;

  • La requête principale peut faire référence à un CTE plusieurs fois, mais avec des alias différents ;

  • Les CTE peuvent être utilisés dans les instructions INSERT, UPDATE et DELETE comme sous-requêtes ;

  • Si le CTE déclaré n’est pas utilisé, un message d’avertissement “CTE cte is not used in query” sera émis. Dans les versions antérieures, une erreur était émise au lieu d’un avertissement ;

  • Les CTE peuvent également être utilisés dans PSQL dans les boucles FOR :

    FOR
      WITH
        MY_RIVERS AS (
          SELECT *
          FROM RIVERS
          WHERE OWNER = 'me'
        )
      SELECT
        NAME,
        LENGTH
      FROM MY_RIVERS
      INTO :RNAME,
           :RLEN
    DO
    BEGIN
      ...
    END
Exemples
Example 1. Requête utilisant CTE
WITH
  DEPT_YEAR_BUDGET AS (
    SELECT
      FISCAL_YEAR,
      DEPT_NO,
      SUM(PROJECTED_BUDGET) BUDGET
    FROM PROJ_DEPT_BUDGET
    GROUP BY FISCAL_YEAR, DEPT_NO
  )
SELECT
  D.DEPT_NO,
  D.DEPARTMENT,
  DYB_2008.BUDGET BUDGET_08,
  DYB_2009.BUDGET AS BUDGET_09
FROM
  DEPARTMENT D
  LEFT JOIN DEPT_YEAR_BUDGET DYB_2008
    ON D.DEPT_NO = DYB_2008.DEPT_NO AND
       DYB_2008.FISCAL_YEAR = 2008
  LEFT JOIN DEPT_YEAR_BUDGET DYB_2009
    ON D.DEPT_NO = DYB_2009.DEPT_NO AND
       DYB_2009.FISCAL_YEAR = 2009
WHERE EXISTS (SELECT *
              FROM PROJ_DEPT_BUDGET B
              WHERE D.DEPT_NO = B.DEPT_NO)