Изменение порядка обработки условий

Оптимизатор изменяет порядок вычисления условий в группах SQL-запроса таким образом, чтобы минимизировать количество промежуточных записей при вычислении каждой группы условий.

Группа условий – это совокупность предикатов, соединенных операциями AND. Записи в ранее вычисленных предикатах группы будут использоваться при вычислении последующих предикатов.

Если группа содержит несколько предикатов одного ранга, то они будут обрабатываться в том порядке, в котором записаны в условии.

Оптимизатор применяет следующий порядок вычисления предикатов в группах:

  1. сначала вычисляются константные предикаты.

    Например,

    1 = 1, (2+4) < = 5

    Подобные условия формируются, в основном, при автоматическом создании SQL-запросов;

  2. затем вычисляются предикаты типа

    < первичный ключ > < OP >  < константа >

    здесь < OP > – это одна из операций: =, LIKE или IN;

  3. следующими вычисляются однопеременные предикаты, в которых участвуют столбцы, не являющиеся первичными ключами и содержащие условия типа «=», LIKE или IN.

    Например,

    < столбец1 > IN (1, 2, 3);
    < столбец1 > LIKE '%alt';
  4. далее вычисляются однопеременные предикаты (т.е. содержащие условия, отличные от «=», LIKE, IN).

    Например,

    B.Y < = 15;
    A.X between 12 and 17;
  5. в последнюю очередь вычисляются многопеременные предикаты.

    При этом несколько следующих друг за другом многопеременных предикатов упорядочиваются таким образом, чтобы переменные, входящие в последующий предикат, в максимальном количестве входили в предыдущие предикаты группы.

    Например,

     Исходная конструкция            Оптимизированная конструкция
    -------------------------------------------------------------
     < условие A.X > = B.X AND         < условие A.X > = B.X AND
     C.Z = D.Z           AND         B.Y = C.Y           AND
     B.Y = C.Y                       C.Z = D.Z

    Из многопеременных предикатов первыми будут вычислены те, которые содержат условия типа «=», LIKE или IN, и только потом остальные.

    Запрос вида

    "SELECT ... FROM
      (SELECT ... FROM A WHERE CONDITION1
    UNION ALL
      SELECT ... FROM B WHERE CONDITION2)
    WHERE
      CONDITION3;"

    преобразуется в запрос

    "SELECT ... FROM
    (SELECT ... FROM A WHERE CONDITION1 AND CONDITION3
     UNION ALL
     SELECT ... FROM B WHERE CONDITION2 AND CONDITION3);"

    Чтобы преобразование произошло, требуется:

    • в качестве CONDITION1, CONDITION2, CONDITION3 должны выступать предикаты и группы предикатов (CONDITION1 и CONDITION2 также могут вообще отсутствовать);

    • внутренние SELECT-запросы не должны использовать функции.