IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  Information Management  >

Статистика групп столбцов в DB2

Улучшение оценок мощность множества результатов в плане доступа

developerWorks
Опции документа

Опции документа, требующие включения JavaScript, не отображаются

Обсудить


Выскажите мнение об этой странице

Помогите нам улучшить содержание


Уровень сложности: сложный

Самир Капур, ведущий аналитик службы поддержки DB2 UDB, IBM
Винсент Корвинелли, консультант по разработке программного обеспечения, IBM

06.06.2007

Используя статистику групп столбцов, оптимизатор DB2® для Linux®, UNIX® и Windows® может определить лучший план доступа для запроса и повысить эффективность его выполнения, если существует корреляция между локальными предикатами равенства или предикатами объединений. В этой статье подробно рассказывается об использовании статистики групп столбцов.

Введение

Оптимизатор SQL DB2 (далее по тексту - оптимизатор) оценивает затраты на выполнение различных вариантов планов доступа и выбирает на основе этих оценок оптимальный план. План доступа определяет порядок действий, необходимых для выполнения SQL-оператора.

Чтобы правильно оценить стоимость выполнения каждого плана, оптимизатору DB2 необходимы точные оценки мощности. Оценкой мощности называется процесс, в ходе которого оптимизатор на основе статистики определяет объемы результатов исполнения частей запроса после применения предикатов или выполнения агрегации. Оптимизатор оценивает мощность результатов работы каждого из операторов, участвующих в плане доступа. Использование одного или нескольких предикатов может сократить мощность выходного потока.

В общем случае при расчете совокупного влияния мощности на фильтрацию предполагается, что предикаты независимы друг от друга. Однако между предикатами может существовать статистическая корреляция. Обычно рассмотрение таких предикатов по отдельности приводит к тому, что оптимизатор недооценивает мощность. Это, в свою очередь, может привести к тому, что будет выбран неоптимальный план доступа.

Для операторов SQL, содержащих два или более локальных предиката равенства, оптимизатор рассматривает статистические корреляции по множеству столбцов и более точно оценивает совокупное фильтрующее действие нескольких предикатов. Кроме того, оптимизатор может использовать статистику по множеству столбцов для операторов SQL, соединяющих две или более таблицы, а также для объединений, применяющих два или более предиката равенства между парой таблиц.

Локальным предикатом равенства называется предикат равенства, накладываемый на одну таблицу; он задается следующим образом:

COLUMN = литеральная константа

где литеральная константа может быть:

  • постоянной величиной;
  • маркером параметра или переменной хоста;
  • специальным регистром (например, CURRENT DATE)

Предикат равенства объединения задается для двух таблиц, T1 и T2, следующим образом:

T1.COLUMN = T2.COLUMN

В DB2 Version 8.2 используется следующая статистика по множеству столбцов:

  • Статистика по карточке ключей индекса : FIRST2KEYCARD, FIRST3KEYCARD, FIRST4KEYCARD и FULLKEYCARD
  • Статистика группы столбцов: мощность группы столбцов

Эти статистические данные описывают количество различных групп для множества из двух или более столбцов.

До версии DB2 Version 8.2 использовалась только статистика по карточке ключей индекса, и только при следующих ограничениях:

  • Индекс должен быть полностью квалифицированным. Индекс считается полностью квалифицированным, если ссылки на все столбцы ключа являются предикатами равенства (объединений или локальными, но не смешанными - и объединений, и локальными).
  • Кроме того, индексы для предикатов объединения должны быть уникальными.

Начиная с версии DB2 Version 8.2 оптимизатор SQL DB2 может использовать статистику по множеству столбцов, учитывая всю статистику по карточке ключей индекса, при этом индекс может не быть полностью квалифицированным. Кроме того, он рассматривает всю статистику групп столбцов, собранную пользователем. В данной статье обсуждается, как оптимизатор использует эту статистику, а также рассматривается вопрос о том, как пользователь может определить, статистику по каким группам столбцов необходимо собрать.



В начало


Статистическая корреляция нескольких локальных предикатов равенства

Оптимизатор SQL DB2 пытается обнаружить статистические корреляции между несколькими локальными предикатами равенства.

Пример 1: Рассмотрим таблицу SHOW_LISTINGS, содержащую следующие столбцы:


Таблица 1. Описание таблицы SHOW_LISTINGS

НАЗВАНИЕ СТОЛБЦА ОПИСАНИЕ
SHOW_IDВнешний ключ к таблице, содержащий информацию о каждой передаче (SHOW) в списке
CHANNEL_IDВнешний ключ к таблице, содержащий информацию о каждом канале (CHANNEL), на котором показывается передача
STATION_IDВнешний ключ к таблице, содержащей информацию о станции (STATION), связанной с каждым из каналов (CHANNEL)
CITY_IDВнешний ключ к таблице, содержащей информацию о городе (CITY), в котором показывается передача (SHOW)
DAYДень (DAY) выхода передачи (SHOW) в эфир
TIMEВремя (TIME) выхода передачи (SHOW) в эфир
<прочие столбцы>Прочие столбцы, описывающие другие атрибуты списков передач

Поскольку передачи (SHOW) показываются только на определенном канале (CHANNEL) и станции (STATION), в определенное время (TIME), то столбцы (SHOW_ID, CHANNEL_ID, STATION_ID и TIME) не являются независимыми друг от друга. Столбец DAY не зависит от столбца TIME, но может зависеть от SHOW_ID для некоторых передач в программе.

Рассмотрим запрос SQL со следующими предикатами:

P1: SHOW_ID = ?
P2: CHANNEL_ID = ?
P3: STATION_ID = ?
P4: TIME = ?

Если существует индекс, ключ которого состоит из всех четырех столбцов, участвующих в предикатах P1-P4, или первые четыре колонки ключа содержат указанные столбцы, оптимизатор на основе статистики индекса FIRST4KEYCARD (если она собрана) определяет статистические корреляции между предикатами P1-P4. В результате оптимизатор более точно рассчитывает оценку мощности при применении всех четырех предикатов . Например, для обнаружения статистической корреляции между четырьмя предикатами может использоваться любой из перечисленных ниже индексов:

IX1 ON SHOW_LISTINGS(SHOW_ID, CHANNEL_ID, STATION_ID, TIME)
IX2 ON SHOW_LISTINGS(SHOW_ID, CHANNEL_ID, STATION_ID, TIME, CITY_ID)
IX3 ON SHOW_LISTINGS(SHOW_ID, CHANNEL_ID, STATION_ID, TIME, DAY, CITY_ID)

Для обнаружения статистической корреляции между четырьмя предикатами оптимизатор использует статистику FULLKEYCARD и FIRST4KEYCARD индекса IX1. Аналогичным образом он может использовать статистику FIRST4KEYCARD индексов IX2 и IX3.

Приведенный ниже индекс использован быть не может:

IX4 ON SHOW_LISTINGS(CITY_ID, SHOW_ID, CHANNEL_ID, STATION_ID, TIME)

поскольку в статистику каждой карточки ключа входит столбец CITY_ID, для которого не определен локальный предикат равенства.

Если индекса с необходимым ключом не существует, можно собрать статистику группы столбцов по SHOW_ID, CHANNEL_ID, STATION_ID и TIME. Оптимизатор использует эту статистику для поиска статистических корреляций между четырьмя предикатами точно так же, как это делалось со статистикой FIRST4KEYCARD из индекса.

Оптимизатор DB2 также рассматривает индексы и статистики групп столбцов для подмножеств предикатов. Например, следующий индекс:

IX5 ON SHOW_LISTINGS(SHOW_ID, STATION_ID, CITY_ID, CHANNEL_ID)

можно использовать для поиска статистических корреляций по предикатам P1 и P3 с помощью статистики FIRST2KEYCARD. Хотя при этом вносится лишь частичная поправка на статистическую корреляцию между предикатами P1-P4, оптимизатору этого может быть достаточно, чтобы выбрать хороший план выполнения. Более того, даже несмотря на то, что полный ключ в индексе IX5 содержит столбец CHANNEL_ID, статистику FULLKEYCARD нельзя использовать для поиска корреляций с P2, поскольку в нее входит столбец CITY_ID, который не участвует в предикатах.



В начало


Статистическая корреляция множества предикатов равенства объединений

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

Пример 2: Рассмотрим таблицу SHOW_LISTINGS, описанную в примере 1, и таблицу RATINGS, содержащую следующие столбцы:


Таблица 2. Описание таблицы RATINGS

НАЗВАНИЕ СТОЛБЦА ОПИСАНИЕ
SHOW_IDВнешний ключ к таблице, содержащей информацию о каждой передаче (SHOW) в списке
CHANNEL_IDВнешний ключ к таблице, содержащей информацию о каждом канале (CHANNEL), на котором показывается передача
STATION_IDВнешний ключ к таблице, содержащей информацию о станции (STATION), связанной с каждым из каналов (CHANNEL)
CITY_IDВнешний ключ к таблице, содержащей информацию о городе (CITY), в котором показывается передача (SHOW)
DAYДень (DAY) выхода передачи (SHOW) в эфир
TIMEВремя (TIME) выхода передачи (SHOW) в эфир
RATINGРейтинг (RATING) передачи (SHOW), выходящей на определенном канале (CHANNEL) и станции (STATION) в определенном городе (CITY) в определенное время (TIME) и день (DAY)

В таблице RATINGS содержится информация, описывающая рейтинги передач в различных городах, и пользователю может понадобиться объединение таблицы RATINGS с таблицей SHOW_LISTINGS для получения атрибутов из двух таблиц. Набор предикатов, накладываемых запросом на объединение, может включать в себя:

P1: SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID
P2: SHOW_LISTINGS.CHANNEL_ID = RATINGS.CHANNEL_ID
P3: SHOW_LISTINGS.STATION_ID = RATINGS.STATION_ID

Три предиката P1-P3 могут не являться независимыми друг от друга; оптимизатор пытается обнаружить корреляцию между предикатами, используя всю доступную статистику по множеству столбцов.

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

P1: T1.A = T2.A
P2: T1.B = T2.B
P3: T1.C = T3.C

Оптимизатор попытается обнаружить статистические взаимоотношения между P1 и P2, поскольку они применяются к объединению одной и той же пары таблиц - T1 и T2. P3 применяется к другому объединению, между таблицами T1 и T3. Пусть теперь мы добавим четвертый предикат, например:

P4: T1.D = T2.D

Оптимизатор попытается обнаружить статистическую корреляцию между P3 и P4.

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

В Приложении B представлены примеры и подробное описание процесса определения оптимизатором родительской и дочерней таблицы в объединении. Знание того, какая из таблиц объединения является родительской и есть ли в объединении родительская таблица, помогает исключить сбор ненужной статистики групп столбцов. Если подходящего индекса ещё не создано, просто соберите статистику групп столбцов по каждой таблице в объединении.



В начало


Сбор статистики по множеству столбцов

Оптимизатор рассматривает возможность использования всей доступной статистики карточек ключей индексов. Если статистика карточек ключей индексов по множеству столбцов, на которые ссылаются статистически связанные предикаты, недоступна, вы можете собрать статистику группы столбцов с помощью команды RUNSTATS. Ниже приведен синтаксис, используемый в DB2 V82.

Примечание: Если вы работаете с DB2 9, вы можете найти соответствующий синтаксис в документации DB2 9, приведенной в Информационном центре.

			>>-RUNSTATS--ON TABLE--table name--+-USE PROFILE------------+--->
                                   '-| Statistics Options |-'
			Statistics Options:

                  			               .-ALLOW WRITE ACCESS-.
			|--+--------------------------+--+--------------------+--------->
   			'-| Table Object Options |-'  '-ALLOW READ ACCESS--'


			Table Object Options:

			|--+-FOR--| Index Clause |----------------------------------+---|
   			   '-+-------------------------+--+-----------------------+-'
     			     '-| Column Stats Clause |-'  '-AND--| Index Clause |-'

			Column Stats Clause:

			|--+-ON--| Cols Clause |------------------------------+---------|
   			   '-+---------------------+--| Distribution Clause |-'
     			     '-ON--| Cols Clause |-'

			On Cols Clause:

   				.-ON ALL COLUMNS-------------------------------------------------.
   				|                                           .-,-------------.    |
   				|                                           V               |    |
			   |--+-ON--+----------------------+--COLUMNS--(----Column Option-+--)-+--|
   			   |     '-+-ALL-+--COLUMNS AND-'                                      |
   				|       '-KEY-'                                                  |
   				'-ON KEY COLUMNS-------------------------------------------------'

			

Оператор "ON COLUMNS" позволяет указать перечень столбцов, для которых необходимо собрать статистику. Если вы укажете группу столбцов, будет собрано количество уникальных значений для группы. Статистика по столбцам, которые не указаны в списке, обнуляется. Этот оператор можно использовать в операторах "on-cols-clause" и "on-dist-cols-clause".

Примечание: На сегодняшний день сбор статистики распределения по группе столбцов не поддерживается.

Примечание: Если включен автоматический сбор статистики и статистика по группе столбцов уже собрана с помощью команды RUNSTATS, автоматический запуск runstats перезапишет статистику по группам столбцов.

Определить, включен ли автоматический сбор статистики, можно по конфигурационному параметру базы данных AUTO_RUNSTATS:

Automatic runstats (AUTO_RUNSTATS)=ON

Если его значение равно "ON", то автоматический сбор статистики включен.

По умолчанию в AUTO_RUNSTATS используется опция RUNSTATS "with distribution and sampled detailed indexes all".

Чтобы переопределить параметры RUNSTATS, назначаемые по умолчанию, вы можете использовать профиль статистики. Чтобы автоматический сбор статистики не перезаписывал собранную вами статистику по группам столбцов, ее необходимо добавить в профиль.

В статье "Изменение профиля статистики" приведена подробная информация о работе с профилем статистики.

В системах, использующих функцию разбиения базы данных (DPF), автоматический сбор статистики включает в себя статистику по разделам каталога. Если этой таблицы нет на узле каталога, используется первый раздел в группе узлов, где содержится данная таблица.

Статистика групп столбцов собирается с применением параметра "ON COLUMNS" команды RUNSTATS. Например, Чтобы собрать статистику по столбцам SHOW_LISTINGS.SHOW_ID, SHOW_LISTINGS.CHANNEL_ID и SHOW_LISTINGS.STATION_ID таблицы SHOW_LISTINGS, необходимо выполнить следующую команду RUNSTATS:

                RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, CHANNEL_ID, 
	STATION_ID))
            

Чтобы собрать статистику только по столбцу DAY и статистику группы столбцов по SHOW_ID, CHANNEL_ID, STATION_ID и TIME, необходимо выполнить следующую команду RUNSTATS:

                RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, CHANNEL_ID, 
	STATION_ID, TIME), DAY)
            

Примечание: Статистика групп столбцов собирается по всем столбцам, перечисленным в группе. В приведенной выше команде также собирается статистика по каждому из столбцов (SHOW_ID, CHANNEL_ID, STATION_ID и TIME).

Чтобы собрать статистику по всем столбцам и статистику группы столбцов по SHOW_ID, CHANNEL_ID, STATION_ID и TIME, необходимо выполнить следующую команду RUNSTATS:

                RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON ALL COLUMNS AND ON COLUMNS 
	((SHOW_ID, CHANNEL_ID, STATION_ID, TIME))
            

Чтобы собрать статистику по нескольким множествам столбцов, можно указать несколько групп. Следующая команда RUNSTATS собирает статистику по множеству столбцов по группам (SHOW_ID, CHANNEL_ID и STATION_ID) и (SHOW_ID, CHANNEL_ID, STATION_ID и TIME), а также статистику столбца DAY:

                RUNSTATS ON TABLE schema_name.SHOW_LISTINGS ON COLUMNS ((SHOW_ID, 
	CHANNEL_ID, STATION_ID), (SHOW_ID, CHANNEL_ID, STATION_ID, TIME), DAY)
            

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



В начало


Когда надо собирать статистику групп столбцов

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

В примерах этого раздела рассматривается база данных SAMPLE, которую можно создать с помощью команды "db2sampl", и используется db2level:

Informational tokens are "DB2 v8.1.1.120", "s060801", "U808888", and FixPak "13".

Пример 3: Локальные предикаты равенства

Сразу после создания базы данных SAMPLE статистика по таблицам отсутствует. Для начала необходимо собрать статистику по таблице EMPLOYEE:

RUNSTATS ON TABLE SCHEMA_NAME.EMPLOYEE WITH DISTRIBUTION;

Рассмотрим следующий запрос к таблице EMPLOYEE из базы данных SAMPLE:

SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY
FROM EMPLOYEE
WHERE JOB='ANALYST';

Этот запрос возвращает две записи из таблицы EMPLOYEE:

EMPNO  FIRSTNME     LASTNAME        WORKDEPT SEX JOB      SALARY     
------ ------------ --------------- -------- --- -------- -----------
000130 DOLORES      QUINTANA        C01      F   ANALYST     23800.00
000140 HEATHER      NICHOLLS        C01      F   ANALYST     28420.00

 2 record(s) selected.

Рассмотрим план выполнения, выбранный для этого запроса.

Для этого используется инструмент EXPLAIN, для работы которого должны быть созданы таблицы EXPLAIN.

  1. Чтобы создать таблицы EXPLAIN, выполните следующую команду:
    db2 -tvf $DB2PATH/misc/EXPLAIN.DDL
    

  2. После того как таблицы EXPLAIN созданы, разъясните запрос следующим образом:
    SET CURRENT EXPLAIN MODE EXPLAIN;
    
    SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY
    FROM EMPLOYEE
    WHERE JOB='ANALYST';
    
    SET CURRENT EXPLAIN MODE NO;
    

    и просмотрите план выполнения запроса с помощью инструмента db2exfmt:
    db2exfmt -d <DBNAME> -1 -g -o <FILENAME>
    

  3. Используя удобный вам текстовый редактор, вы должны увидеть план выполнения, подобный следующему:
    
            2 
         TBSCAN 
         (   2) 
         30.8464 
            2 
           |
           32 
     TABLE: SKAPOOR 
        EMPLOYEE
    
    

    Оценка мощности 2 соответствует реальному результату.

  4. Добавим к запросу несколько избыточных предикатов равенства:
    
    SELECT EMPNO, FIRSTNME, LASTNAME, WORKDEPT, SEX, JOB, SALARY
    FROM EMPLOYEE
    WHERE JOB='ANALYST' AND SEX='F' AND WORKDEPT='C01';
    
    

    Этот запрос возвращает такой же результат, как и приведенный выше запрос. Однако если посмотреть на план выполнения запроса, созданный с помощью EXPLAIN, видно, что оценка мощности не соответствует фактическому результату:

        0.0761719 
         TBSCAN 
         (   2) 
         31.4115 
            2 
           |
           32 
     TABLE: SKAPOOR 
        EMPLOYEE
    

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

  5. Соберем статистику групп по столбцам JOB, WORKDEPT и SEX.
    RUNSTATS ON TABLE <SCHEMA_NAME>.EMPLOYEE ON ALL COLUMNS AND COLUMNS 
    	((JOB, WORKDEPT, SEX)) WITH DISTRIBUTION;
    

    Имея статистику групп столбцов по трем столбцам, оптимизатор DB2 выдает лучшую оценку мощности:

         1.77778 
         TBSCAN 
         (   2) 
         31.4214 
            2 
           |
           32 
     TABLE: SKAPOOR 
        EMPLOYEE
    

    Оценка мощности не является точной, как в запросе с одним предикатом (2), поскольку статистика группы столбцов представляет собой однородное распределение.

Пример 4: Предикаты равенства для объединений

В этом примере рассматривается объединение между таблицами ORG и STAFF. Для начала необходимо собрать статистику по этим таблицам. Сначала собираем основную статистику:


RUNSTATS ON TABLE <SCHEMA_NAME>.ORG;
RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF;


Рассмотрим следующий запрос, соединяющий таблицы ORG и STAFF:


SELECT STAFF.NAME, ORG.DEPTNUMB, ORG.DEPTNAME, STAFF.SALARY
FROM ORG, STAFF
WHERE ORG.MANAGER = STAFF.ID AND ORG.DEPTNUMB = STAFF.DEPT
ORDER BY ORG.DEPTNUMB;


Этот запрос возвращает восемь записей:


NAME      DEPTNUMB DEPTNAME       SALARY   
--------- -------- -------------- ---------
Molinare        10 Head Office     22959.20
Hanes           15 New England     20659.80
Sanders         20 Mid Atlantic    18357.50
Marenghi        38 South Atlantic  17506.75
Plotz           42 Great Lakes     18352.80
Fraye           51 Plains          21150.00
Lea             66 Pacific         18555.50
Quill           84 Mountain        19818.00

  8 record(s) selected.


  1. Просмотрим план выполнения запроса с помощью инструмента EXPLAIN:
    
                    1 
                 TBSCAN 
                 (   2) 
                 33.2225 
                    2 
                   |
                    1 
                 SORT   
                 (   3) 
                 33.151 
                    2 
                   |
                    1 
                 HSJOIN 
                 (   4) 
                 33.0248 
                    2 
              /-----+-----\
           35                8 
         TBSCAN           TBSCAN 
         (   5)           (   6) 
         17.2334          15.3736 
            1                1 
           |                |
           35                8 
     TABLE: SKAPOOR  TABLE: SKAPOOR 
          STAFF             ORG
    
    

    В этом примере используется простой метод сбора статистики групп столбцов. В Приложении B приведен этот же пример с более глубоким анализом, позволяющим определить родительскую таблицу в объединении.

  2. Объединение выполняется по столбцам ID и DEPT таблицы STAFF и столбцам MANAGER и DEPTNUMB таблицы ORG, поэтому соберем статистику групп столбцов по этим двум множествам столбцов:
    
    RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF ON ALL COLUMNS AND COLUMNS ((ID, DEPT));
    RUNSTATS ON TABLE <SCHEMA_NAME>.ORG ON ALL COLUMNS AND COLUMNS ((MANAGER, DEPTNUMB));
    
    

Используя эту статистику групп столбцов, оптимизатор DB2 правильно оценивает мощность запроса:

               8
             TBSCAN 
             (   2) 
             33.5658 
                2 
               |
               8
             SORT   
             (   3) 
             33.4243 
                2 
               |
               8      
             HSJOIN 
             (   4) 
             33.0363 
                2 
          /-----+-----\
       35                8 
     TBSCAN           TBSCAN 
     (   5)           (   6) 
     17.2334          15.3736 
        1                1 
       |                |
       35                8 
 TABLE: SKAPOOR  TABLE: SKAPOOR 
      STAFF             ORG


Пример 5: Просмотр статистики по множеству столбцов

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

Вариант 1. Использование инструмента db2look

Инструмент db2look используется для генерации запросов DDL, воссоздающих объекты, определенные в базе данных. С помощью параметра -m можно вывести статистику, собранную для этих объектов.

  1. Соберем статистику групп столбцов и индексов для таблицы ORG:
    CREATE INDEX IX1 ON ORG (DEPTNUMB, DEPTNAME, MANAGER);
    
    RUNSTATS ON TABLE <SCHEMA_NAME>.ORG ON ALL COLUMNS
             AND COLUMNS ((DEPTNUMB, DEPTNAME, MANAGER, DIVISION, LOCATION))
             WITH DISTRIBUTION AND INDEXES ALL;
    

  2. Просмотрим статистику по таблице ORG с помощью db2look:
    db2look -d sample -e -a -m -t ORG -o org.ddl
    

    Примечание: Для просмотра информации об инструменте DB2look можно воспользоваться параметром -h.

  3. Просмотрите вывод команды в файле org.ddl. Он должен содержать следующий запрос UPDATE для сбора статистики групп столбцов:
    
    UPDATE SYSSTAT.COLGROUPS SET colgroupcard = 8
            WHERE colgroupid IN (SELECT colgroupid
            FROM SYSCAT.COLGROUPCOLS
            WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
                  AND colname = 'DEPTNUMB' AND oridnal = 1)
            AND colgroupid IN (SELECT colgroupid
            FROM SYSCAT.COLGROUPCOLS
            WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
                  AND colname = 'DEPTNAME' AND oridnal = 2)
            AND colgroupid IN (SELECT colgroupid
            FROM SYSCAT.COLGROUPCOLS
            WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
                  AND colname = 'MANAGER' AND oridnal = 3)
            AND colgroupid IN (SELECT colgroupid
            FROM SYSCAT.COLGROUPCOLS
            WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
                  AND colname = 'DIVISION' AND oridnal = 4)
            AND colgroupid IN (SELECT colgroupid
            FROM SYSCAT.COLGROUPCOLS
            WHERE tabschema = 'SKAPOOR ' AND tabname = 'ORG'
                  AND colname = 'LOCATION' AND oridnal = 5)
            AND colgroupid NOT IN (SELECT colgroupid
            FROM SYSCAT.COLGROUPCOLS
            WHERE tabschema = 'SKAPOOR ' 
                  AND tabname = 'ORG' AND oridnal = 6) ;
    
    

    Примечание: Расчет статистики групп столбцов реализован в инструменте db2look в версии 8, пакете исправлений 13.

    Приведенный выше запрос перечисляет все столбцы представления SYSCAT.COLGROUPCOLS и соответствующую статистику по множеству столбцов из SYSSTAT.COLGROUPS, представляющую количество уникальных групп в этом множестве столбцов. В рассматриваемом примере приведенный выше оператор описывает набор столбцов (DEPTNUMB, DEPTNAME, MANAGER, DIVISION и LOCATION), имеющий восемь уникальных групп.

    В файле org.ddl также содержится следующий запрос для статистики индекса:

    UPDATE SYSSTAT.INDEXES
    SET NLEAF=1,
        NLEVELS=1,
        FIRSTKEYCARD=8,
        FIRST2KEYCARD=8,
        FIRST3KEYCARD=8,
        FIRST4KEYCARD=-1,
        FULLKEYCARD=8,
        CLUSTERFACTOR=-1.000000,
        CLUSTERRATIO=100,
        SEQUENTIAL_PAGES=0,
        DENSITY=0,
        AVERAGE_SEQUENCE_GAP=0.000000,
        AVERAGE_SEQUENCE_FETCH_GAP=0.000000,
        AVERAGE_SEQUENCE_PAGES=0.000000,
        AVERAGE_SEQUENCE_FETCH_PAGES=0.000000,
        AVERAGE_RANDOM_PAGES=1.000000,
        AVERAGE_RANDOM_FETCH_PAGES=0.000000,
        NUMRIDS=8,
        NUMRIDS_DELETED=0,
        NUM_EMPTY_LEAFS=0
    WHERE INDNAME = 'IX1' AND INDSCHEMA = 'SKAPOOR'
          AND TABNAME = 'ORG' AND TABSCHEMA = 'SKAPOOR';
    

    Приведенный выше запрос на обновление описывает следующую статистику по множеству столбцов. Статистика FIRST2KEYCARD описывает количество уникальных групп в столбцах (DEPTNUMB,DEPTNAME), а FIRST3KEYCARD и FULLKEYCARD - количество уникальных групп во всем множестве столбцов (DEPTNUMB,DEPTNAME,MANAGER). Значение FIRST4KEYCARD равно -1, поскольку в ключе индекса содержится всего 3 столбца.

Вариант 2. Запрос к таблицам каталога

Ту же информацию, что содержится в выводе утилиты DB2look, можно запросить из таблиц каталога DB2.

  1. Если индекс еще не создан, создайте его (так, как это было описано выше, в шаге 1 варианта 1), и соберите статистику по множеству столбцов для нескольких таблиц:
    RUNSTATS ON TABLE <SCHEMA_NAME>.ORG ON ALL COLUMNS
             AND COLUMNS ((DEPTNUMB, DEPTNAME, MANAGER, DIVISION, LOCATION), 
             (DEPTNUMB, DEPTNAME), (MANAGER, DIVISION)) WITH DISTRIBUTION AND INDEXES ALL;
    
    RUNSTATS ON TABLE <SCHEMA_NAME>.EMPLOYEE ON ALL COLUMNS 
             AND COLUMNS ((EMPNO, WORKDEPT), (EMPNO, WORKDEPT, JOB));
    

  2. Для получения статистики групп столбцов создайте запрос к таблицам каталога. Следует отметить, что приведенный ниже SQL-запрос является рекурсивным, это приведет к возникновению предупреждения SQL0347W, которое можно игнорировать. Это предупреждение можно с помощью опции "UPDATE COMMAND OPTIONS USING W OFF".
    WITH TMP(ID, NUM) AS
    (
       SELECT COLGROUPID, MAX(ORIDNAL)
         FROM SYSCAT.COLGROUPCOLS
       GROUP BY COLGROUPID
    ),
    TMP2 (ID, NAME, NUM, TNAME, TSCHEMA) AS
    (
       SELECT ID, CAST(RTRIM(COLNAME) AS CHAR(128)), NUM, TABNAME, TABSCHEMA
         FROM TMP Y, SYSCAT.COLGROUPCOLS X
        WHERE X.COLGROUPID = Y.ID
          AND Y.NUM = X.ORIDNAL
      UNION ALL
       SELECT Y.ID, CAST(RTRIM(X.COLNAME) || ',' || Y.NAME AS CHAR(128)), Y.NUM-1,
       	 TNAME, TSCHEMA
         FROM TMP2 Y, SYSCAT.COLGROUPCOLS X
        WHERE Y.ID=X.COLGROUPID
          AND X.ORIDNAL=Y.NUM-1
          AND Y.NUM > 1
          AND TNAME = TABNAME
          AND TSCHEMA = TABSCHEMA
    )
    SELECT SUBSTR(TSCHEMA,1,10) TABSCHEMA, SUBSTR(TNAME,1,10) TABNAME, 
    	NAME COLS, COLGROUPCARD 
    FROM TMP2, SYSSTAT.COLGROUPS
    WHERE ID = COLGROUPID
    AND NUM = 1
    ORDER BY TABSCHEMA, TABNAME
    ;
    

    Приведенный выше запрос возвращает следующие записи:

    Примечание: Значение столбца TABSCHEMA будет отличаться от приведенного здесь. Кроме того, столбец COLS результата преобразуется в тип CHAR(128), что приведет к усечению результата, если его длина превышает 128 символов. Если это так, вам может потребоваться изменить оператора CAST на строковой тип большей длины.

    TABSCHEMA  TABNAME    COLS                                   COLGROUPCARD        
    ---------- ---------- ------------------------------//------ -----------------
    SKAPOOR    EMPLOYEE   EMPNO,WORKDEPT                                        32
    SKAPOOR    EMPLOYEE   EMPNO,WORKDEPT,JOB                                    32
    SKAPOOR    ORG        DEPTNUMB,DEPTNAME                                      8
    SKAPOOR    ORG        MANAGER,DIVISION                                       8
    SKAPOOR    ORG        DEPTNUMB,DEPTNAME,MANAGER,DIVISION,LOCATION            8
    
      5 record(s) selected with 1 warning messages suppressed.
    

    Записи описывают статистику по группе из двух столбцов таблицы EMPLOYEE и статистику по группе из трех столбцов таблицы ORG.

    Примечание: В вышеприведенном запросе обратите внимание на столбец "ORIDNAL" в представлении SYSCAT.SYSCOLGROUPCOLS. В DB2 9 написание исправлено на правильное: "ORDINAL", поэтому чтобы использовать запрос в DB2 9, необходимо изменить его следующим образом:

    WITH TMP(ID, NUM) AS
    (
       SELECT COLGROUPID, MAX(ORDINAL)
         FROM SYSCAT.COLGROUPCOLS
       GROUP BY COLGROUPID
    ),
    TMP2 (ID, NAME, NUM, TNAME, TSCHEMA) AS
    (
       SELECT ID, CAST(RTRIM(COLNAME) AS CHAR(128)), NUM, TABNAME, TABSCHEMA
         FROM TMP Y, SYSCAT.COLGROUPCOLS X
        WHERE X.COLGROUPID = Y.ID
          AND Y.NUM = X.ORDINAL
      UNION ALL
       SELECT Y.ID, CAST(RTRIM(X.COLNAME) || ',' || Y.NAME AS CHAR(128)), Y.NUM-1,
       	 TNAME, TSCHEMA
         FROM TMP2 Y, SYSCAT.COLGROUPCOLS X
        WHERE Y.ID=X.COLGROUPID
          AND X.ORDINAL=Y.NUM-1
          AND Y.NUM > 1
          AND TNAME = TABNAME
          AND TSCHEMA = TABSCHEMA
    )
    SELECT SUBSTR(TSCHEMA,1,10) TABSCHEMA, SUBSTR(TNAME,1,10) TABNAME, NAME COLS,
    	 COLGROUPCARD 
    FROM TMP2, SYSSTAT.COLGROUPS
    WHERE ID = COLGROUPID
    AND NUM = 1
    ORDER BY TABSCHEMA, TABNAME
    ;
    

  3. Для получения статистики индексов создайте запрос к таблицам каталога.

    Примечание: Замените значение в предикате TABSCHEMA='SKAPOOR' на соответствующее название вашей схемы.

    SELECT SUBSTR(COLNAMES, 1, 30) AS COLS, FIRST2KEYCARD, FIRST3KEYCARD,
    	 FIRST4KEYCARD, FULLKEYCARD
    FROM SYSSTAT.INDEXES
    WHERE TABSCHEMA='SKAPOOR' AND TABNAME='ORG';
    

    Приведенный выше запрос возвращает следующую запись:

    COLS                       FIRST2KEYCARD FIRST3KEYCARD FIRST4KEYCARD FULLKEYCARD
    -------------------------- ------------- ------------- ------------- -----------
    +DEPTNUMB+DEPTNAME+MANAGER             8             8            -1           8
    
      1 record(s) selected.
    

    Статистика FIRST2KEYCARD описывает количество уникальных групп в столбцах (DEPTNUMB и EPTNAME), а FIRST3KEYCARD и FULLKEYCARD - количество уникальных групп во всем множестве столбцов (DEPTNUMB, EPTNAME и MANAGER). Значение FIRST4KEYCARD равно -1, поскольку в ключе индекса содержится всего три столбца.



В начало


Упражнения

В обоих примерах 3 и 4, для правильной оценки мощности за счет учета статистической корреляции оптимизатор может использовать статистику индекса вместо статистики групп столбцов.

Попробуйте выполнить следующие действия:

  1. Создайте следующие индексы:
    IXEMP_1 ON EMPLOYEE(JOB, WORKDEPT, SEX);
    IXSTAFF_1 ON STAFF(ID, DEPT);
    IXORG_1 ON ORG(MANAGER, DEPTNUMB);
    

  2. Соберите статистику по индексам и не собирайте статистику групп столбцов:
    RUNSTATS ON TABLE <SCHEMA_NAME>.EMPLOYEE AND INDEXES ALL;
    RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF AND DETAILED INDEXES ALL;
    RUNSTATS ON TABLE <SCHEMA_NAME>.ORG AND INDEXES ALL;
    

  3. Разъясните запросы из примеров 3 и 4. Оценка мощности получается такой же, как и в плане выполнения приведенного выше запроса; однако сам план выполнения может быть другим, поскольку присутствуют индексы. Следует отметить, что сбор подробной (DETAILED) статистики по индексу не влияет на оценку мощности.
  4. Удалите два индекса, IXEMP_1 и IXSTAFF_1, созданные на шаге 1, и создайте два новых индекса:
    IXEMP_1 ON EMPLOYEE(JOB, WORKDEPT, SEX, EMPNO);
    IXSTAFF_1 ON STAFF(ID, DEPT,NAME,JOB);
    

  5. Повторите шаги 2 и 3. В результате получаем ту же оценку мощности.


В начало


Приложение A. Использование профиля автоматического сбора статистики

Утилита RUNSTATS предоставляет возможность регистрации и использования профиля сбора статистики. Функция профиля автоматического сбора статистики DB2 также позволяет автоматически создавать профили сбора статистики. При включении этой функции информация о действиях, совершаемых в базе данных, собирается и записывается в хранилище откликов запросов. На основе этих данных создается профиль статистики. Эта функция также рекомендует использовать для локальных предикатов равенства статистику по группам из двух столбцов. Этот инструмент может быть полезен в тестовых средах для выявления полезных статистик групп столбцов.

В Информационном центре имеется дополнительная информация об использовании профилей автоматического сбора статистики.

Примечание: Автоматическое создание профилей статистики может быть включено только в последовательном режиме работы DB2, оно недоступно в федерированной среде, в среде с разбиением (DPF), а также при использовании параллелизма внутри разделов.



В начало


Приложение B. Определение родительской таблицы в объединении

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

Оптимизатор определяет родительскую таблицу в множестве предикатов двух соединяемых таблиц как таблицу, которая является родительской хотя бы в одном предикате объединения и не является дочерней в других предикатах объединения. Родительская таблица предиката объединения определяется как таблица с большим количеством уникальных значений столбца предиката. Например, если в предикат объединения SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID, статистика COLCARD по столбцу SHOW_LISTINGS.SHOW_ID больше, чем статистика COLCARD столбца RATINGS.SHOW_ID, то SHOW_LISTINGS будет родительской таблицей в условии объединения, а RATINGS - дочерней.

Кроме того, для проверки правильности выбора родительской таблицы оптимизатор пытается использовать статистику диапазонов (HIGH2KEY and LOW2KEY), при этом множество значений дочерней таблицы должно быть подмножеством значений родительской таблицы. Например, если в предикате объединения SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID:

  • статистика COLCARD столбца SHOW_LISTINGS.SHOW_ID больше, чем статистика COLCARD столбца RATINGS.SHOW_ID, и
  • статистика HIGH2KEY столбца SHOW_LISTINGS.SHOW_ID больше или равна статистике HIGH2KEY столбца RATINGS.SHOW_ID, и
  • статистика LOW2KEY столбца RATINGS.SHOW_ID меньше или равна статистике LOW2KEY столбца RATINGS.SHOW_ID

то таблица SHOW_LISTINGS является родительской в предикате объединения, а RATINGS - дочерней.

Пример B.1

Рассмотрим следующий набор предикатов:

P1: SHOW_LISTINGS.SHOW_ID = RATINGS.SHOW_ID
P2: SHOW_LISTINGS.CHANNEL_ID = RATINGS.CHANNEL_ID
P3: SHOW_LISTINGS.STATION_ID = RATINGS.STATION_ID

В P1 предположим, что COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID).

В P2 предположим, что COLCARD(SHOW_LISTINGS.CHANNEL _ID) > COLCARD(RATINGS.CHANNEL_ID).

В P3 предположим, что COLCARD(SHOW_LISTINGS.STATION_ID) > COLCARD(RATINGS.STATION_ID).

оптимизатор определяет таблицу SHOW_LISTINGS как родительскую во всех предикатах, поэтому он также считает ее родительской в объединении. В результате оптимизатор использует статистику по множеству столбцов, созданную для столбцов (SHOW_ID, CHANNEL_ID и STATION_ID) таблицы SHOW_LISTINGS.

Пример B.2

Используя предикаты из примера B.1:

В P1 предположим, что COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID).

В P2 предположим, что COLCARD(SHOW_LISTINGS.CHANNEL _ID) > COLCARD(RATINGS.CHANNEL_ID).

В P3 предположим, что COLCARD(SHOW_LISTINGS.STATION_ID) = COLCARD(RATINGS.STATION_ID).

оптимизатор определяет таблицу SHOW_LISTINGS как родительскую в предикатах P1 и P2, и считает, что она является не родительской и не дочерней в условии P3. Поэтому он также определяет таблицу SHOW_LISTINGS как родительскую в объединении. В результате оптимизатор использует статистику по множеству столбцов, созданную для столбцов (SHOW_ID, CHANNEL_ID и STATION_ID) таблицы SHOW_LISTINGS.

Пример B.3

Используя предикаты из примера B.1:

В P1 предположим, что COLCARD(SHOW_LISTINGS.SHOW_ID) > COLCARD(RATINGS.SHOW_ID).

В P2 предположим, что COLCARD(SHOW_LISTINGS.CHANNEL _ID) < COLCARD(RATINGS.CHANNEL_ID).

В P3 предположим, что COLCARD(SHOW_LISTINGS.STATION_ID) = COLCARD(RATINGS.STATION_ID).

оптимизатор определяет таблицу SHOW_LISTINGS как родительскую в предикате P1, как дочернюю в предикате P2, и считает, что она не является ни родительской, ни дочерней в условии P3. Поэтому он не идентифицирует таблицу SHOW_LISTINGS как родительскую таблицу объединения (равно как и RATINGS). В результате оптимизатор не пытается обнаружить статистические корреляции между этими тремя предикатами объединений.

Функция разбиения базы данных

Если таблица в среде DPF разбита на несколько разделов базы данных, вы можете использовать только статистику диапазонов, если соблюдены следующие условия:

  1. обе таблицы разбиты по одним и тем же столбцам
  2. таблицы являются соседними, то есть они расположены в одной группе узлов
  3. предикаты объединения указывают на все столбцы ключа разбиения
  4. статистика собирается на том же узле

Если статистику по диапазонам использовать не получается, оптимизатор будет использовать для определения родительской таблицы в объединении только статистику COLCARD. В среде DPF статистика собирается на одном узле, что может привести к неточному значению COLCARD. Поэтому при определении родительской таблицы оптимизатор оставляет допуск (1%) на значение COLCARD. Однако этот допуск основывается на статистике по множеству столбцов, поэтому если объединение не нейтральное, и ни одна из таблиц не является очевидно родительской, в среде DPF следует использовать простой подход к сбору статистики.

Пример B.4

1. Убедитесь, что обе таблицы разбиты по одним и тем же столбцам

Вы не можете использовать статистику по диапазонам (HIGH2KEY и LOW2KEY), если данные в обеих таблицах не распределены одинаково. Поэтому, если таблицы не разбиты по одним и тем же столбцам, оптимизатор не будет считать, что данные распределены одинаково в обеих таблицах.

Рассмотрим две таблицы T1 и T2. Таблица T1 разбита на несколько разделов базы данных, ключ разбиения создан по столбцам (C1 и C2). Аналогичным образом таблица T2 также разбита, при этом ключ разбиения создан по столбцам (C2 и C3).

Случай 1.1 При использовании следующих предикатов для объединения T1 и T2:

P1:  T1.C1=T2.C2
P2:  T1.C2=T2.C3

таблицы считаются разбитыми по одним и тем же столбцам, поскольку предикаты объединения накладываются в том же порядке, что в соответствующих ключах разбиения.

Случай 1.2 При использовании следующих предикатов:

P1:  T1.C1=T2.C3
P2:  T1.C2=T2.C2

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

Случай 1.3 При использовании следующих предикатов:

P1: T1.C1=T2.C1
P2: T1.C2=T2.C2
P3: T1.C3=T2.C3

таблицы не считаются разбитыми по одним и тем же столбцам.

Случай 1.4 Рассмотрим ситуацию, в которой предикаты такие же, как и в случае 1.3, но предположим, что таблица T2 разбита по столбцам (C1, C2 и C3).

Несмотря на то, что таблица T1 разбита по тем же столбцам, что и два первых столбца в ключе разбиения T2, таблица T2 также разбита и по столбцу C3, что может привести к иному распределению данных, по сравнению с разбиением только по (C1 и C2). Поэтому таблицы не считаются разбитыми по одним и тем же столбцам.

2. Выясняем, являются ли две таблицы соседними

Рассмотрим две таблицы, T1 и T2, при этом таблица T1 принадлежит к группе узлов N0, а T2 - к группе узлов N1, где N0 содержит разделы с номерами 0 и 1, а N1 - соответственно, 1 и 2. Поскольку таблицы не принадлежат к одной группе узлов, они не могут считаться соседними.

3. Выясняем, ссылаются ли предикаты объединения на все столбцы ключа разбиения

Рассмотрим две таблицы, T1 и T2. Таблица T1 разбита на несколько разделов базы данных, ключ разбиения создан по столбцам (C1 и C2). Аналогичным образом, таблица T2 также разбита, ключ разбиения создан по столбцам (C2 и C3).

Пример 3.1 Использование предикатов для объединения таблиц T1 и T2:

P1:  T1.C1=T2.C2
P2:  T1.C2=T2.C3

оба предиката охватывают все столбца ключа разбиения.

Пример 3.2 Если к примеру 3.1 добавить третий предикат, P3, как T1.C3=T2.C1, то три предиката вместе также будут охватывать все столбцы ключа разбиения в обеих таблицах. Однако если мы оставим только P1 и P3, все столбцы ключа разбиения охвачены не будут.

Пример 3.3 Если к примеру 3.1 добавить третий предикат, P3, как T1.C3=T2.C2, то три предиката вместе также будут охватывать все столбцы ключа разбиения в обеих таблицах. Однако если мы оставим только предикаты P1 и P3, будут охвачены столбцы T2, но не будут охвачены столбца T1, поэтому условие не выполняется.

Полностью квалифицированный уникальный индекс

Если ни одна из таблиц не обозначена как родительская таблица объединения на основе перечисленных выше условий, оптимизатор проводит проверку на наличие полностью квалифицированного уникального индекса. Если предикаты объединения полностью квалифицируют уникальный индекс, оптимизатор использует статистику FULLKEYCARD уникального индекса для поиска и учета статистических корреляций между предикатами равенства объединений.

Нейтральные объединения

Оптимизатор считает объединение между двумя таблицами нейтральным, если он не нашел в предикатах равенства объединений двух таблиц родительской и дочерней таблицы. Родительская таблица для предиката равенства объединения не определяется, если статистики COLCARD обоих столбцов равны и оба столбца охватывают один и тот же диапазон значений (статистики HIGH2KEY и LOW2KEY равны).

В DB2 версии 8, пакете исправлений 13, и более ранних версиях оптимизатор не учитывает статистические корреляции между множеством предикатов равенства объединения двух таблиц, если это объединение нейтральное. В версии 8, пакет исправлений 14, и в DB2 9 механизм обнаружения статистических корреляций оптимизатора учитывает также и статистические корреляции нейтральных объединений.

Внутреннее объединение, в котором обе таблицы ссылаются на одну и ту же базовую таблицу, является особым случаем нейтрального объединения. Оптимизатор учитывает статистическую корреляцию для этого особого случая начиная с версии 8.2.

Пример B.5: Сбор статистики групп столбцов для родительской таблицы

В этом примере рассматривается объединение между таблицами ORG и STAFF. Для начала необходимо собрать статистику по этим таблицам. Сначала собираем основную статистику:

RUNSTATS ON TABLE <SCHEMA_NAME>.ORG;
RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF;

Рассмотрим следующий запрос, соединяющий таблицы ORG и STAFF:

SELECT STAFF.NAME, ORG.DEPTNUMB, ORG.DEPTNAME, STAFF.SALARY
FROM ORG, STAFF
WHERE ORG.MANAGER = STAFF.ID AND ORG.DEPTNUMB = STAFF.DEPT
ORDER BY ORG.DEPTNUMB;

Этот запрос возвращает восемь записей:


NAME      DEPTNUMB DEPTNAME       SALARY   
--------- -------- -------------- ---------
Molinare        10 Head Office     22959.20
Hanes           15 New England     20659.80
Sanders         20 Mid Atlantic    18357.50
Marenghi        38 South Atlantic  17506.75
Plotz           42 Great Lakes     18352.80
Fraye           51 Plains          21150.00
Lea             66 Pacific         18555.50
Quill           84 Mountain        19818.00

 8 record(s) selected.


1. Просмотрим план выполнения запроса с помощью инструмента EXPLAIN:


                1 
             TBSCAN 
             (   2) 
             33.2225 
                2 
               |
                1 
             SORT   
             (   3) 
             33.151 
                2 
               |
                1 
             HSJOIN 
             (   4) 
             33.0248 
                2 
          /-----+-----\
       35                8 
     TBSCAN           TBSCAN 
     (   5)           (   6) 
     17.2334          15.3736 
        1                1 
       |                |
       35                8 
 TABLE: SKAPOOR  TABLE: SKAPOOR 
      STAFF             ORG
      

2. Рассмотрим статистику столбцов, указанных в предикатах объединения. Приведенный ниже запрос возвращает интересующую нас статистику столбцов из таблиц каталога DB2 для столбцов таблиц ORG и STAFF, участвующих в двух предикатах объединения:


SELECT SUBSTR(COLNAME,1,20) AS COLNAME, COLCARD,
       SUBSTR(HIGH2KEY,1,10) AS HIGH2KEY,
       SUBSTR(LOW2KEY,1,10) AS LOW2KEY
FROM SYSSTAT.COLUMNS
WHERE TABNAME IN ('ORG', 'STAFF')
AND COLNAME IN ('MANAGER', 'DEPTNUMB', 'ID', 'DEPT')
ORDER BY TABNAME, COLNAME;


Таблица B.5 Статистика столбцов

COLNAME COLCARD HIGH2KEY LOW2KEY
DEPTNUMB86615
MANAGER827030
DEPT86615
ID3534020

3. Рассчитаем оценку мощности.

Оценка коэффициента фильтрации предиката равенства объединения рассчитывается как

1/max(colcard_LHS,colcard_RHS).

где LHS - это левая сторона предиката объединения, а RHS - правая сторона этого предиката. В данном случае у нас есть два предиката объединения:

P1: org.manager=staff.id
P2: org.deptnumb=staff.dept

коэффициенты фильтрации (ff) для P1 и P2 рассчитываются как:

ff(P1) = 1 / max (8,35) = 1/35 = 0.0285714
ff(P2) = 1/max(8,8) = 1/8 = 0.125

На основании оценки коэффициентов фильтрации и мощности двух таблиц мощность объединения рассчитывается как:

JoinCard  = Cardinality(ORG) * cardinality(STAFF) * ff(P1) * ff(P2)
          = 35 * 8 * 0.0285714 * 0.125
          = 1

4. Определим родительскую таблицу объединения.

Из статистики столбцов, приведенной в таблице B.5, видно, что родительской таблицей в объединении является таблица STAFF, поскольку выполняются следующие условия:

Для предиката org.manager=staff.id:

colcard(MANAGER)  < colcard(ID)
high2key(MANAGER) < high2key(ID)
low2key(MANAGER) > low2key(ID)

Следовательно, таблица STAFF является родительской для этого предиката.

Для предиката org.deptnumb=staff.dept статистики colcard, high2key и low2key равны. Таким образом, родительской таблицы для этого предиката нет, он считается "нейтральным".

5. Сбор статистики групп столбцов для родительской таблицы.

В шаге 4 было установлено, что родительской таблицей объединения является таблица STAFF, а ORG, соответственно, дочерней, поэтому статистику групп столбцов необходимо собирать по столбцам (ID, DEPT) таблицы STAFF:

RUNSTATS ON TABLE <SCHEMA_NAME>.STAFF ON ALL COLUMNS AND COLUMNS ((ID,DEPT));

Используя статистику групп по двум столбцам, оптимизатор DB2 правильно оценивает мощность запроса:


               8  
             TBSCAN 
             (   2) 
             33.5658 
               2 
               |
               8
              SORT   
             (   3) 
             33.4243 
               2 
               |
               8
             HSJOIN 
             (   4) 
             33.0363 
                2 
          /-----+-----\
       35                8 
     TBSCAN           TBSCAN 
     (   5)           (   6) 
     17.2334          15.3736 
        1                1 
       |                |
       35                8 
 TABLE: SKAPOOR  TABLE: SKAPOOR 
      STAFF             ORG


Пример B.6 Нейтральное объединение

Рассмотрим объединение двух таблиц, T1 и T2, по следующим предикатам:

    
P1: T1.C1 = T2.C1
P2: T1.C2 = T2.C2
P3: T1.C3 = T2.C3

Предположим, статистика таблиц выглядит следующим образом:


Таблица B.6 Статистика нейтрального объединения

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY
T1C1100992T2C1100992
T1C21019991900T2C21019991900
T1C35'Y''B'T2C35'Y''B'

Все предикаты обозначены как нейтральные, поскольку статистики для обоих таблиц равны. Поэтому в версии 8, пакете исправлений 14, и в DB2 9 необходимо собрать статистику групп столбцов (C1, C2 и C3) по любой таблице (не обязательно по обеим), чтобы оптимизатор мог обнаружить статистическую корреляцию между предикатами объединения.

Пример B.7

Используя те же предикаты, что и в примере B.6, предположим, что статистика столбцов имеет следующий вид:


Таблица B.7 Определение родительской таблицы

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY
T1C1100992T2C110992
T1C21019991900T2C21019991900
T1C35'Y''B'T2C35'Y''B'

В этом случае предикаты P2 и P3 считаются нейтральными, поскольку статистика для столбцов C2 и C3 обеих таблиц эквивалентна. Однако статистика для C1 показывает, что T1 является родительской в P1, поскольку COLCARD столбца T1.C1 больше, чем COLCARD столбца T2.C1, а статистики HIGH2KEY и LOW2KEY для обоих столбцов равны. Поэтому для того, чтобы оптимизатор мог обнаружить статистическую корреляцию между двумя предикатами объединения, необходимо собрать статистику групп столбцов (C1, C2 и C3) таблицы T1.

Пример B.8

Используя те же предикаты, что и в примере B.6, предположим, что статистика столбцов имеет следующий вид:


Таблица B.8 Статистика столбцов

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY
T1C1100992T2C1109992
T1C21019991900T2C21019991900
T1C35'Y''B'T2C35'Y''B'

В этом случае предикаты P2 и P3 считаются нейтральными, поскольку статистика для столбцов C2 и C3 обеих таблиц эквивалентна. Однако статистика C1 показывает, что ни T1, ни T2 не являются ни родительскими, ни нейтральными, поскольку у T1.C1 выше значение COLCARD, а у T2.C1 выше значение HIGH2KEY. Поэтому для того, чтобы оптимизатор мог обнаружить статистическую корреляцию между двумя предикатами объединения P2 и P3, необходимо собрать статистику групп столбцов (C2, C3 и C1) таблицы T1 или T2.

Пример B.9 Использование DPF и статистики диапазонов

Рассмотрим объединение двух таблиц, T1 и T2, разбитых на несколько разделов базы данных. Они являются соседними, статистика собрана на одном и том же узле, ключи разбиения таблиц T1 и T2 созданы по столбцам (C1 и C2), а объединение выполняется по следующим предикатам:

    
P1: T1.C1 = T2.C1
P2: T1.C2 = T2.C2
P3: T1.C3 = T2.C3

Предположим, статистика таблиц выглядит следующим образом:


Таблица B.9

TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY TABLENAME COLNAME COLCARD HIGH2KEY LOW2KEY
T1C1100992T2C1109992
T1C21019991900T2C21019991900
T1C35'Y''B'T2C35'Y''B'

Это объединение подпадает под условия DPF, поэтому оптимизатор может использовать для выявления родительской стороны статистику диапазонов. В этом случае предикаты P2 и P3 считаются нейтральными, поскольку статистика для столбцов C2 и C3 обеих таблиц эквивалентна. Однако статистика C1 показывает, что ни T1, ни T2 не являются ни родительскими, ни нейтральными, поскольку у T1.C1 выше значение COLCARD, а у T2.C1 выше значение HIGH2KEY. Поэтому для того, чтобы оптимизатор мог обнаружить статистическую корреляцию между двумя предикатами объединения, P2 и P3, необходимо собрать статистику групп столбцов (C2 и C3) таблицы T1 или T2.

Пример B.10 DPF и случай, когда статистика по диапазонам не может быть использована

Рассмотрим тот же сценарий, что и в примере B.9, изменив ключ разбиения T2 на столбцы (C2 и C1), тогда как ключ разбиения T1 остается по столбцам (C1 и C2). Это объединение не удовлетворяет первому условию DPF, так как таблицы не считаются разбитыми по одинаковым столбцам; предикаты объединения T1.C1=T2.C1 ссылаются на первый столбец в ключе разбиения T1 и на второй столбец в ключе разбиения T2. В результате оптимизатор н