Главная страница
Навигация по странице:

  • 5. Оборудование

  • 7. Контрольные вопросы

  • Лабораторная работа №12 Индексирование 1. Цель и задачи работы

  • 2. Порядок выполнения работы

  • 3. Оформление отчета

  • 4. Теоретические сведения

  • Лабораторные_БД_ЭВМ_20 (AutoRecovered). Методические указания по выполнению лабораторных работ по дисциплине (модулю)


    Скачать 0.75 Mb.
    НазваниеМетодические указания по выполнению лабораторных работ по дисциплине (модулю)
    Дата05.05.2022
    Размер0.75 Mb.
    Формат файлаdocx
    Имя файлаЛабораторные_БД_ЭВМ_20 (AutoRecovered).docx
    ТипМетодические указания
    #512616
    страница8 из 12
    1   ...   4   5   6   7   8   9   10   11   12


    Пример.Процедура raise_salary, которая увеличивает жалованье сотрудника:

    CREAT OR REPLACE PROCEDUREraise_salary (emp_id NUMBER, increase REAL) IS current_salary REAL; salary_missing EXCEPTION;

    BEGIN

    SELECT sal INTO current_salaryFROMemp

    WHERE empno =emp_id;

    IF current_salary IS NULL THEN

    RAISE salary_missing;

    ELSE

    UPDATE emp SET sal = sal +increase

    WHERE empno = emp_id;

    END IF;

    EXCEPTION

    WHEN NO_DATA_FOUND THEN

    INSERT INTO emp_auditVALUES(emp_id, 'No such number'); WHEN salary_missing THEN

    INSERT INTO emp_auditVALUES(emp_id, 'Salary is null');

    END raise _ salary ;

    Функции

    Функция – это подпрограмма, которая вычисляет значение. Функции структурируются так же, как и процедуры, с той разницей, что функции содержат фразу RETURN. Вы пишете функции, используя синтаксис

    FUNCTIONимя [ (аргумент [, аргумент, ...]) ]RETURN тип_данныхIS[локальные_объявления]BEGIN

    исполняемые предложения

    [EXCEPTIONобработчики исключений]END [имя]; где каждый "аргумент" имеет следующий синтаксис: имя_перем [IN | OUT | IN OUT] тип_данных [{:= | DEFAULT} знач]

    В исполняемой части процедуры должно встретиться хотя бы одно предложение RETURN.

    Процедура начинается с ключевых слов CREATE PROCEDURE, за которыми следует ее имя и список параметров. В качестве ключевого слова (описателя) вместо CREATE может использоваться ORREPLACE. Преимущество использования этого ключевого слова в том, что если процедура с каким-то именем уже определена, то новое определение с тем же именем не вызовет ошибки. С другой стороны, предыдущее определение процедуры с аналогичным именем заменится новым определением, и старая процедура перестанет существовать.

    Пример:

    функция balance возвращает баланс заданного бухгалтерского счета:

    CREATE OR REPLACE FUNCTION balance(acct_id NUMBER)RETURN REAL ISacct_bal REAL;

    BEGIN

    SELECT bal INTO acct_bal FROM acctsWHEREacctno = acct_id;

    RETURN acct_bal;

    END balance;
    5. Оборудование

    персональный компьютер с установленной операционной системой Windows XP/7/8, браузер (Например, InternetExplorer, GoogleChrome, Opera), СУБД PostgreSQL.
    6. Задание на работу

    1. Создайте функцию, возвращающую количество записей в таблице по указанному значению внешнего ключа. Входной параметр - значение ключа.

    2. Создайте процедуру, изменяющую поле строки. Входные параметры - первичный ключ строки и новое значение изменяемого поля.

    3. Создайте новую таблицу TEMP для занесения временных данных. Напишите процедуру (используя явный курсор) для выборки первых пяти записей какой-либо таблицы, соответствующих определенному критерию, и занесения их в таблицу TEMP.

    4. Приведите:

    • смысл процедуры или функции на языке, понятном пользователю в данной предметной области.

    • оператор, создающий данную процедуру или функцию

    • состояние данных до выполнения процедуры или функции

    • оператор, запускающий процедуру или функцию

    • состояние данных после выполнения процедуры или функции


    7. Контрольные вопросы

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

    2. В базе данных basa1 имеется таблица Город. Из базы данных basa2 необходимо выполнить действие по увеличению тарифов для всех городов на 15%. В какой базе данных должна быть создана процедура и как можно ее выполнить?

    3. В базе данных basa1 имеется таблица Блюдо. Из базы данных basa2 необходимо выполнить действие по увеличению стоимости всех блюд на 50%. В какой базе данных должна быть создана процедура и как можно ее выполнить?

    4. В базе данных basa1 имеется таблица Рейс. Из базы данных basa2 необходимо выполнить действие по увеличению стоимости билетов на все рейсы на 25%. В какой базе данных должна быть создана процедура и как можно ее выполнить?

    5. В базе данных basa1 имеется таблица Книга. Из базы данных basa2 необходимо выполнить действие по увеличению цены всех книг на 10%. В какой базе данных должна быть создана процедура и как можно ее выполнить?

    6. В базе данных basa1 имеется таблица Рейс. Содержащуюся в ней информацию необходимо прочитать из базы данных basa2. В какой базе данных должна быть создана процедура, и как можно ее выполнить?


    Лабораторная работа №12

    Индексирование
    1. Цель и задачи работы

    Целью лабораторной работы является изучение и практическое применение индексирования.
    2. Порядок выполнения работы

    - ознакомится с теоретическими сведениями;

    - выполнить задание;

    - оформить отчет;

    - ответить на контрольные вопросы, заданные преподавателем.
    3. Оформление отчета

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

    Индексы – это традиционное средство увеличения производительности БД. Используя индекс, сервер баз данных может находить и извлекать нужные строки гораздо быстрее, чем без него. Однако с индексами связана дополнительная нагрузка на СУБД в целом, поэтому применять их следует обдуманно.

    Предположим, что у нас есть такая таблица:

    CREATE TABLE test1 (

    id integer,

    content varchar

    );

    и приложение выполняет много подобных запросов:

    SELECT content FROM test1 WHERE id = константа;

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

    Задача программиста баз данных – заранее определить, какие индексы будут полезны.

    Создать индекс для столбца id рассмотренной ранее таблицы можно с помощью следующей команды:

    CREATE INDEX test1_id_index ON test1 (id);

    Имя индекса test1_id_index может быть произвольным, главное, чтобы оно позволяло понять, для чего этот индекс.

    Для удаления индекса используется команда DROP INDEX. Добавлять и удалять индексы можно в любое время.

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

    Индексы могут быть полезны также при выполнении команд UPDATE и DELETE с условиями поиска. Кроме того, они могут применяться в поиске с соединением. То есть, индекс, определённый для столбца, участвующего в условии соединения, может значительно ускорить запросы с JOIN.

    Создание индекса для большой таблицы может занимать много времени. По умолчанию PostgreSQL позволяет параллельно с созданием индекса выполнять чтение (операторы SELECT) таблицы, но операции записи (INSERT, UPDATE и DELETE) блокируются до окончания построения индекса. Для производственной среды это ограничение часто бывает неприемлемым. Хотя есть возможность разрешить запись параллельно с созданием индексов.

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

    PostgreSQL поддерживает несколько типов индексов: B-дерево, хеш, GiST, SP-GiST, GIN и BRIN. Для разных типов индексов применяются разные алгоритмы, ориентированные на определённые типы запросов. По умолчанию команда CREATE INDEX создаёт индексы типа B-дерево, эффективные в большинстве случаев.

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

    <

    <=

    =

    >=

    >

    При обработке конструкций, представимых как сочетание этих операторов, например BETWEEN и IN, так же может выполняться поиск по индексу-B-дереву. Кроме того, такие индексы могут использоваться и в условиях IS NULL и IS NOT NULL по индексированным столбцам.

    Также оптимизатор может использовать эти индексы в запросах с операторами сравнения по шаблону LIKE и 

    , если этот шаблон определяется константой и он привязан к началу строки – например, col LIKE 'foo%' или col '^foo', но не col LIKE '%bar'. Но если ваша база данных использует не локаль C, для поддержки индексирования запросов с шаблонами вам потребуется создать индекс со специальным классом операторов. Индексы-B-деревья можно использовать и для ILIKE и *, но только если шаблон начинается не с алфавитных символов, то есть символов, не подверженных преобразованию регистра.

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

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

    CREATE INDEX имя ON таблица USING HASH (столбец);

    Операции с хеш-индексами в настоящее время не проходят через WAL, так что после аварийной остановки базы данных может потребоваться перестроить хеш-индексы командой REINDEX. Кроме того, изменения в хеш-индексах после начальной копии не переносятся при потоковой или файловой репликации, так что в последующих запросах они будут давать неправильные ответы. По этим причинам настоятельно рекомендуется не использовать их.

    GiST-индексы представляют собой не просто разновидность индексов, а инфраструктуру, позволяющую реализовать много разных стратегий индексирования. Как следствие, GiST-индексы могут применяться с разными операторами, в зависимости от стратегии индексирования (класса операторов). Например, стандартный дистрибутив PostgreSQL включает классы операторов GiST для нескольких двумерных типов геометрических данных, что позволяет применять индексы в запросах с операторами:

    <<

    &<

    &>

    >>

    <<|

    &<|

    |&>

    |>>

    @>

    <@

    =

    &&

    Классы операторов GiST, включённые в стандартный дистрибутив. В коллекции contrib можно найти и другие классы операторов GiST, реализованные как отдельные проекты.

    GiST-индексы также могут оптимизировать поиск «ближайшего соседа», например такой:

    SELECT * FROM places ORDER BY location <-> point '(101,456)' LIMIT 10;

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

    Индексы SP-GiST, как и GiST, предоставляют инфраструктуру, поддерживающие различные типы поиска. SP-GiST позволяет организовывать на диске самые разные несбалансированные структуры данных, такие как деревья квадрантов, k-мерные и префиксные деревья. Например, стандартный дистрибутив PostgreSQL включает классы операторов SP-GiST для точек в двумерном пространстве, что позволяет применять индексы в запросах с операторами:

    <<

    >>

    =

    <@

    <^

    >^

    Классы операторов SP-GiST, включённые в стандартный дистрибутив. GIN-индексы представляют собой инвертированные индексы, в которых могут содержаться значения с несколькими ключами, например массивы. Подобно GiST и SP-GiST, индексы GIN могут поддерживать различные определённые пользователем стратегии и в зависимости от них могут применяться с разными операторами. Например, стандартный дистрибутив PostgreSQL включает классы операторов GIN для одномерных массивов, что позволяет применять индексы в запросах с операторами:

    <@

    @>

    =

    &&

    Классы операторов GIN, включённые в стандартный дистрибутив. В коллекции contrib можно найти и другие классы операторов GIN, реализованные как отдельные проекты.

    BRIN-индексы (сокращение от Block Range indexes, Индексы зон блоков) хранят обобщённые сведения о значениях, находящихся в физически последовательно расположенных блоках. Подобно GiST, SP-GiST и GIN, индексы BRIN могут поддерживать определённые пользователем стратегии, и в зависимости от них применяться с разными операторами. Для типов данных, имеющих линейный порядок сортировки, записям в индексе соответствуют минимальные и максимальные значения данных в столбце для каждой зоны блоков, что позволяет поддерживать запросы со следующими операторами:

    <

    <=

    =

    >=

    >

    Классы операторов BRIN, включённые в стандартный дистрибутив.

    Индексы можно создавать и по нескольким столбцам таблицы. Например, если у вас есть таблица:

    CREATE TABLE test2 (

    major int,

    minor int,

    name varchar

    );

    (предположим, что вы поместили в неё содержимое каталога /dev) и вы часто выполняете запросы вида:

    SELECT name FROM test2 WHERE major = константа AND minor = константа;

    тогда имеет смысл определить индекс, покрывающий оба столбца major и minor. Например:

    CREATE INDEX test2_mm_idx ON test2 (major, minor);

    В настоящее время составными могут быть только индексы типов B-дерево, GiST, GIN и BRIN. Число столбцов в индексе ограничивается 32 (этот предел можно изменить при компиляции PostgreSQL).

    Составной индекс-B-дерево может применяться в условиях с любым подмножеством столбцов индекса, но наиболее эффективен он при ограничениях по ведущим (левым) столбцам. Точное правило состоит в том, что сканируемая область индекса определяется условиями равенства с ведущими столбцами и условиями неравенства с первым столбцом, не участвующим в условии равенства. Ограничения столбцов правее них также проверяются по индексу, так что обращение к таблице откладывается, но на размер сканируемой области индекса это уже не влияет. Например, если есть индекс по столбцам (a, b, c) и условие WHERE a=5 AND b>=42 AND c<77, индекс будет сканироваться от первой записи a=5 и b=42 до последней с a=5. Записи индекса, в которых c >= 77, не будут учитываться, но, тем не менее, будут просканированы. Этот индекс в принципе может использоваться в запросах с ограничениями по b и/или c, без ограничений столбца a, но при этом будет просканирован весь индекс, так что в большинстве случаев планировщик предпочтёт использованию индекса полное сканирование таблицы.

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

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

    Составной индекс BRIN может применяться в условиях запроса с любым подмножеством столбцов индекса. Подобно индексу GIN и в отличие от B-деревьев или GiST, эффективность поиска по нему не меняется в зависимости от того, какие из его столбцов используются в условиях запроса. Единственное, зачем в одной таблице могут потребоваться несколько индексов BRIN вместо одного составного индекса — это затем, чтобы применялись разные параметры хранения pages_per_range.

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

    Составные индексы следует использовать обдуманно. В большинстве случаев индекс по одному столбцу будет работать достаточно хорошо и сэкономит время и место. Индексы по более чем трём столбцам вряд ли будут полезными, если только таблица не используется крайне однообразно.

    Помимо простого поиска строк для выдачи в результате запроса, индексы также могут применяться для сортировки строк в определённом порядке. Это позволяет учесть предложение ORDER BY в запросе, не выполняя сортировку дополнительно. Из всех типов индексов, которые поддерживает PostgreSQL, сортировать данные могут только B-деревья – индексы других типов возвращают строки в неопределённом, зависящем от реализации порядке.

    Планировщик может выполнить указание ORDER BY, либо просканировав существующий индекс, подходящий этому указанию, либо просканировав таблицу в физическом порядке и выполнив сортировку явно. Для запроса, требующего сканирования большой части таблицы, явная сортировка скорее всего будет быстрее, чем применение индекса, так как при последовательном чтении она потребует меньше операций ввода/вывода. Важный особый случай представляет ORDER BY в сочетании с LIMIT n: при явной сортировке системе потребуется обработать все данные, чтобы выбрать первые n строк, но при наличии индекса, соответствующего столбцам в ORDER BY, первые n строк можно получить сразу, не просматривая остальные вовсе.

    По умолчанию элементы B-дерева хранятся в порядке возрастания, при этом значения NULL идут в конце. Это означает, что при прямом сканировании индекса по столбцу x порядок оказывается соответствующим указанию ORDER BY x (или точнее, ORDER BY x ASC NULLS LAST). Индекс также может сканироваться в обратную сторону, и тогда порядок соответствует указанию ORDER BY x DESC (или точнее, ORDER BY x DESC NULLS FIRST, так как для ORDER BY DESC подразумевается NULLS FIRST).

    Вы можете изменить порядок сортировки элементов B-дерева, добавив уточнения ASCDESCNULLS FIRST и/или NULLS LAST при создании индекса; например:

    CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);

    CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);

    Индекс, в котором элементы хранятся в порядке возрастания и значения NULL идут первыми, может удовлетворять указаниям ORDER BY x ASC NULLS FIRST или ORDER BY x DESC NULLS LAST, в зависимости от направления просмотра.

    У вас может возникнуть вопрос, зачем нужны все четыре варианта при создании индексов, когда и два варианта с учётом обратного просмотра покрывают все виды ORDER BY. Для индексов по одному столбцу это и в самом деле излишне, но для индексов по многим столбцам это может быть полезно. Рассмотрим индекс по двум столбцам (x, y): он может удовлетворять указанию ORDER BY x, y при прямом сканировании или ORDER BY x DESC, y DESC при обратном. Но вполне возможно, что приложение будет часто выполнять ORDER BY x ASC, y DESC. В этом случае получить такую сортировку от простого индекса нельзя, но можно получить подходящий индекс, определив его как (x ASC, y DESC) или (x DESC, y ASC).

    Очевидно, что индексы с нестандартными правилами сортировки весьма специфичны, но иногда они могут кардинально ускорить определённые запросы. Стоит ли вводить такие индексы, зависит от того, как часто выполняются запросы с необычным порядком сортировки.

    При простом сканировании индекса могут обрабатываться только те предложения в запросе, в которых применяются операторы его класса и объединяет их AND. Например, для индекса (a, b) условие запроса WHERE a = 5 AND b = 6 сможет использовать этот индекс, а запрос WHERE a = 5 OR b = 6 – нет.

    К счастью, PostgreSQL способен соединять несколько индексов (и в том числе многократно применять один индекс) и охватывать также случаи, когда сканирования одного индекса недостаточно. Система может сформировать условия AND и OR за несколько проходов индекса. Например, запрос WHERE x = 42 OR x = 47 OR x = 53 OR x = 99 можно разбить на четыре сканирования индекса по x, по сканированию для каждой части условия. Затем результаты этих сканирований будут логически сложены (OR) вместе и дадут конечный результат. Другой пример – если у нас есть отдельные индексы по x и y, запрос WHERE x=5 AND y=6 можно выполнить, применив индексы для соответствующих частей запроса, а затем вычислив логическое произведение (AND) для найденных строк, которое и станет конечным результатом.

    Выполняя объединение нескольких индексов, система сканирует все необходимые индексы и создаёт в памяти битовую карту расположения строк таблицы, которые удовлетворяют условиям каждого индекса. Затем битовые карты объединяются операциями AND и OR, как того требуют условия в запросе. Наконец система обращается к соответствующим отмеченным строкам таблицы и возвращает их данные. Строки таблицы просматриваются в физическом порядке, как они представлены в битовой карте; это означает, что порядок сортировки индексов при этом теряется и в запросах с предложением ORDER BY сортировка будет выполняться отдельно. По этой причине, а также потому, что каждое сканирование индекса занимает дополнительное время, планировщик иногда выбирает простое сканирование индекса, несмотря на то, что можно было бы подключить и дополнительные индексы.

    В большинстве приложений (кроме самых простых) полезными могут оказаться различные комбинации индексов, поэтому разработчик баз данных, определяя набор индексов, должен искать компромиссное решение. Иногда оказываются хороши составные индексы, а иногда лучше создать отдельные индексы и положиться на возможности объединения индексов. Например, если типичную нагрузку составляют запросы иногда с условием только по столбцу x, иногда только по y, а иногда по обоим столбцам, вы можете ограничиться двумя отдельными индексами по x и y, рассчитывая на то, что при обработке условий с обоими столбцами эти индексы будут объединяться. С другой стороны, вы можете создать один составной индекс по (x, y). Этот индекс скорее всего будет работать эффективнее, чем объединение индексов, в запросах с двумя столбцами, но он будет практически бесполезен для запросов с ограничениями только по y, так что одного этого индекса будет недостаточно. Выигрышным в этом случае может быть сочетание составного индекса с отдельным индексом по y. В запросах, где задействуется только x, может применяться составной индекс, хотя он будет больше и, следовательно, медленнее индекса по одному x. Наконец, можно создать все три индекса, но это будет оправдано, только если данные в таблице изменяются гораздо реже, чем выполняется поиск в таблице, при этом частота запросов этих трёх типов примерно одинакова. Если запросы какого-то одного типа выполняются гораздо реже других, возможно лучше будет оставить только два индекса, соответствующих наиболее частым запросам.

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

    CREATE UNIQUE INDEX имя ON таблица (столбец [, ...]);

    В настоящее время уникальными могут быть только индексы-B-деревья.

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

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

    Хотя индексы в PostgreSQL не требуют какого-либо обслуживания или настройки, это не избавляет от необходимости проверять, как и какие индексы используются на самом деле в реальных условиях. Узнать, как отдельный запрос использует индексы, можно с помощью команды EXPLAIN. Также возможно собрать общую статистику об использовании индексов на работающем сервере.

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

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

    • Используйте в экспериментах реальные данные. Анализируя работу системы с тестовыми данными, вы поймёте, какие индексы нужны для тестовых данных, но не более того.

    Особенно сильно искажают картину очень маленькие наборы тестовых данных. Тогда как для извлечения 1000 строк из 100000 может быть применён индекс, для выбора 1 из 100 он вряд ли потребуется, так как 100 строк скорее всего уместятся в одну страницу данных на диске и никакой другой план не будет лучше обычного сканирования 1 страницы.

    Тем не менее, пока приложение не эксплуатируется, создавать какие-то тестовые данные всё равно нужно, и это нужно делать обдуманно. Если вы наполняете базу данных очень близкими, или наоборот, случайными значениями, либо добавляете строки в отсортированном порядке, вы получите совсем не ту статистику распределения, что дадут реальные данные.

    • Когда индексы не используются, ради тестирования может быть полезно подключить их принудительно. Для этого можно воспользоваться параметрами выполнения, позволяющими выключать различные типы планов. Например, выключив наиболее простые планы: последовательное сканирование (enable_seqscan) и соединения с вложенными циклами (enable_nestloop), вы сможете заставить систему выбрать другой план. Если же система продолжает выполнять сканирование или соединение с вложенными циклами, вероятно, у неё есть более серьёзная причина не использовать индекс; например, индекс может не соответствовать условию запроса.

    • Если система начинает использовать индекс только под принуждением, тому может быть две причины: либо система права и применять индекс в самом деле неэффективно, либо оценка стоимости применения индекса не соответствует действительности. В этом случае вам следует замерить время выполнения запроса с индексами и без них. В анализе этой ситуации может быть полезна команда EXPLAIN ANALYZE.

    • Если выясняется, что оценка стоимости неверна, это может иметь тоже два объяснения. Общая стоимость вычисляется как произведение цены каждого узла плана для одной строки и оценки избирательности узла плана. Цены узлов при необходимости можно изменить параметрами выполнения. С другой стороны, оценка избирательности может быть неточной из-за некачественной статистики. Улучшить её можно, настроив параметры сбора статистики.

    Более подробная информация: PostgreSQL : Документация: 9.5: Индексы
    1   ...   4   5   6   7   8   9   10   11   12


    написать администратору сайта