itmo_conspects

Лекция 7. Производительность

В прошлой лекции мы убедились, что нормализация (декомпозиция отношений) увеличивает целостность, но понижает производительность

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

Индекс

Один из таких подходов - использование индекса

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

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

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

Тут же можем выделить 3 типа индекса:

Первичный индекс - индекс, созданный по первичному ключу отношения, которое упорядочено по первичному ключу

И с первичным индексом можем найти недостаток: хранение отсортированного порядка отношения (дорого, но обеспечиваем дешевый джоин); и преимущество: скорость поиска

Индекс кластеризации - индекс, созданный по неключевому полю отношения, которое упорядочено по этому полю

Заметим, что индекс получается неплотным - он не указывает на каждый кортеж. Из-за этого отношение группируется в кластеры по значению избранного поля.

Вторичный индекс - индекс, построенный по полю не упорядоченного по нему отношения

Из определения очевидно, что поле должно быть уникальным ключом - отношение не упорядочено, значит, кластеров не будет.

Заметим, что при этом два индекса сразу мы не можем создать для одной таблицы - и на этом концепция индекса заканчивается

Индекс также различают по плотности на:

Плотный индекс - индекс, в котором одному узлу соответствует одна запись

Разреженный индекс - индекс, в которому одному узлу соответствуют несколько записей

А если мы начнем делать индекс для атрибута-строки, то мы неизбежно придем к хеш-фукнциям, и тут тоже есть свои нюансы, например, для электронных почтовых адресов используют хеш от реверса строки, чтобы не допускать естественную кластеризацию

Представление

Второй же подход - это представления

Допустим такую модель:

“Студент”

ИСУ ФИО N группы Форма обучения
       

“Группа”

N группы ОП
   

“Образовательная программа”

ОП Факультет
   

“Паспорт”

ИСУ Паспорт
   

Индексы в этом ситуации будут бесполезны

Появляется идея: что, если вместе с нормализованной моделью хранить и денормализованную:

ИСУ ФИО N группы Форма обучения ОП Факультет
           

Тут приходим к:

Представление - динамически сформированный результат одной или нескольких реляционных операций, выполненных с целью получения нового отношения

Представления делятся на материализованные и представления заменой

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

По сути материализованное представление - это банальный кеш. И тут возникает проблема неактуальности кеша: допустим ситуацию, что база данных актуализируется ночью; студент в день комиссии утром подписывает заявление об академическом отпуске, а вечером комиссия, которая не знает о его уходе, отчисляет его🦆

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

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

Представления могут быть обновляемыми и необновляемыми, но не все представления могут быть обновляемыми из-за race-condition. Хороший пример на эту тему - воскрешение студента: студент подал заявление на перевод между группами в июле, но эта транзакция перевода должна выполниться в сентябре, на комиссии его отчислили, но транзакция по переводу групп выполнилась после отчисления, и, таким образом, его зачислили обратно🦆

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

Здесь выделим преимущества представления:

И недостатки представления:


И по большей части это все костыли, которые сломали невыполнимую идею Кодда. Но тем не менее все эти недостатки и преимущства - баланс, в котором мы ищем решение