Что означает создание индекса по иерархическому признаку

Русские Блоги

Используйте pandas для анализа данных (два): индекс и иерархический индекс

Индексный метод Series и DataFrame

Видимый Series Метод индексации очень прост, вы можете индексировать по его метке индекса или индексировать по номеру. нужно знать, pandas Небольшая разница между средним индексом и срезом состоит в том, что включен конец индекса. Посмотри снова DataFrame Индекс и метод доступа:

DataFrame Он имеет атрибуты строки и столбца, поэтому в дополнение к обычному индексу столбца в индексе индекс строки также является хорошим способом доступа к данным:

При индексировании нескольких столбцов по имени столбца один list форма. Посмотри снова DataFrame Способ индексации по строкам:

иерархический индекс панд

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

loc Этот метод также может достичь того же эффекта доступа к индексу:

Если вы считаете, что многоуровневый индекс Series Это некрасиво, также можно пройти прямо unstack Метод преобразования его в DataFrame :

unstack с stack Обратные операции друг друга, преобразованные DataFrame Также может пройти stack Путь назад.

Выше Series Метод иерархической индексации, давайте посмотрим DataFrame Иерархический индекс:

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

Источник

Иерархические данные (SQL Server)

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

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

группа задач в проекте;

Классификация языковых терминов

Диаграмма связей между веб-страницами

Основные свойства типа hierarchyid

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

Среднее число бит, необходимое для представления узла в древовидной структуре с n узлами, зависит от среднего количества потомков у узла. Для структур с низкой степенью ветвления (0-7) объем занимаемой памяти равен примерно 6*logA n бит, где A — среднее ветвление. Для представления узла в иерархии организации, насчитывающей 100 000 человек со средним уровнем ветвления 6, необходимо около 38 бит. Эта величина округляется до 40 бит (5 байт), которые необходимы для хранения.

Сравнение проводится в порядке приоритета глубины

Связанные задачи

Переход со структуры «родители-потомки» на тип hierarchyid

Большинство деревьев представлены методом «родители-потомки». Для перехода со структуры «родители-потомки» на тип hierarchyid проще всего создать временный столбец или временную таблицу для хранения количества узлов на каждом уровне иерархии. Пример преобразования таблицы с организацией «родители-потомки» см. в статье Учебник. Использование типа данных hierarchyid(урок 1).

Управление древовидной структурой с помощью hierarchyid

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

При формировании новых значений выполните одно из следующих действий.

Следите за последним номером потомка в строке родитель.

Вычислите последнего потомка. Для эффективного вычисления требуется наличие индекса по ширине.

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

Определяйте нарушения уникальных ключей и проводите повторные попытки.

Определите уникальность каждого нового дочернего узла перед его вставкой с использованием сериализуемой транзакции.

Пример использования обнаружения ошибок

Пример использования сериализуемой транзакции

Индекс Org_BreadthFirst обеспечивает использование поиска по диапазону для определения значения @last_child. В дополнение к другим случаям ошибок, проверка которых может потребоваться приложению, нарушение повторяющихся ключей после вставки может свидетельствовать о попытке добавления нескольких сотрудников с одним и тем же идентификатором; вследствие этого вычисление значения @last_child должно быть выполнено повторно. Следующий код вычислит новое значение узла в сериализуемой транзакции:

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

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

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

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

Поиск предков с помощью среды CLR

Одной из частых операций, в которых участвуют два узла из иерархии, является нахождение ближайшего общего предка. Эта операция может быть описана в среде Transact-SQL либо в среде CLR, поскольку тип данных hierarchyid доступен в обеих. Рекомендуется использовать среду CLR, поскольку она обеспечивает большую производительность.

Используйте следующий код CLR, чтобы найти список предков и ближайшего общего предка:

Перечисление предков

Использование среды Transact-SQL:

Нахождение ближайшего общего предка

Результирующий узел — /1/1/

Перемещение поддеревьев

Другой распространенной операцией является перемещение поддеревьев. Описанная ниже процедура берет поддерево узла @oldMgr и делает его (включая сам узел @oldMgr) поддеревом узла @newMgr.

Источник

Создание физической модели базы данных: проектирование производительности

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

Введение

Повышение производительности запросов: индексы

Индексирование

Индексирование (indexing) — это способ обеспечения быстрого доступа к значениям колонки или комбинации колонок. Физически новые строки добавляются в конец таблицы, результатом чего становится неупорядоченное размещение значений в колонках. Без использования каких-либо методов упорядочения данных единственным способом просмотра значения колонки со стороны СУБД является последовательный просмотр каждой строки от начала таблицы к ее концу — так называемое сканирование таблицы. Производительность такого сканирования пропорциональна размеру таблицы, размеру физической страницы БД и длине строки таблицы.

Одним из способов внесения отношения порядка в значения колонок без нарушения физического расположения строк таблицы является создание объекта реляционной СУБД — индекса (index). Индекс — это объект в реляционной БД, который предназначен для организации быстрого доступа к строкам таблицы по значениям одной или более колонок этих строк.

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

Основными целями создания индексов в БД являются:

Индекс со структурой B-Tree

Индекс на основе сбалансированной иерархической структуры (или индекс B-Tree, balanced tree structured object) напоминает дерево, если смотреть на него снизу вверх. При работе СУБД с этой структурой сначала считывается самый верхний блок — корневой узел (root), затем блок на следующем уровне — блок-ветвь (branch), и так далее, до тех пор, пока не будет извлечен блок-лист ( leaf ) с индексируемыми колонками (колонкой) строки. Обратим внимание, что значения индексируемых колонок сохраняется в индексе ( рис. 20.1).

Что означает создание индекса по иерархическому признаку

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

Индекс B-Tree характеризуется количеством уровней в индексе – высотой (height). Чем меньше уровней, тем выше производительность.

В СУБД семейства MS SQL Server все индексы организованы на основе сбалансированной иерархической структуры. Помимо того, что индексы обладают свойствами уникальности ( UNIQUE ) и неуникальности, индексы в СУБД семейства MS SQL Server могут быть кластеризованными ( CLUSTERED ) или некластеризованными ( NONCLUSTERED ), являющимися индексами по умолчанию.

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

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

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

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

Если таблица является кучей (то есть не содержит кластеризованный индекс ), то указатель строки является указателем на строку. Указатель строится на основе идентификатора файла ( ID ), номера страницы и номера строки на странице. Весь указатель целиком называется идентификатором строки ( RID ).

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

Таблица 20.1. Описание полей таблицы «Служащий» (EMPLOYEE)

Наименование атрибутаНаименование колонки
1Номер личной карточкиEMPNO (PK)
2ФамилияENAME
3ИмяLNAME
4Номер подразделенияDEPNO
5ДолжностьJOB
6Дата рожденияAGE
7СтажHIREDATE
8ДоплатыCOMM
9ЗарплатаSAL
10ШтрафыFINE
11АвтобиографияBiog
12ФотографияFoto

Что означает создание индекса по иерархическому признаку

Создадим для таблицы «Служащий» (EMPLOYEE) составной индекс по колонкам «Фамилия» (Ename) и «Должность» (Job).

Источник

Иерархические битовые индексы

Что означает создание индекса по иерархическому признаку

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

Теория битовых индексов достигла уровня зрелости, позволяющего архитекторам баз данных корректно ставить разработчикам задачу на расширение стандартного функционала битовых индексов для конкретной СУБД. Несмотря на то что для этого потребуется детальное изучение нюансов задачи, результат в виде кратного повышения производительности этого стоит.
29 ноября 2018 года эта тема подробно обсуждается на конференции «Технологии управления данными 2018»

Понятие битовых индексов (bitmap index) хорошо знакомо каждому проектировщику баз данных. Впервые введенные в 1987 году, они стали стандартным способом оптимизации запросов в промышленных СУБД: Oracle, Cache и др. Однако эффективность их использования сильно зависит как от запросов, так и от особенностей базы данных. В [1] раскрываются некоторые секреты и развенчиваются устойчивые заблуждения по поводу битовых индексов, но в целом литературы на русском языке крайне мало, а между тем в зависимости от задачи можно использовать не битовые индексы в виде, предоставляемом СУБД, а их модификацию, что существенно повышает эффективность поиска, причем затраты на такую модификацию с лихвой окупаются повышением производительности обработки запросов.

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

Количество подходов, учитывающих эти и другие факторы, сегодня очень велико. Изучение и развитие теории и практики битовых индексов идет по трем основным направлениям: сжатие (compression), кодирование (encoding) и группирование (binning).

Остановимся подробнее на третьем, наиболее важном для понимания концепции иерархических индексов. Желающим же ознакомиться с основными теоретическими достижениями по битовым индексам в их историческом развитии можно порекомендовать обзор [5].

Что означает создание индекса по иерархическому признаку

Идея группирования достаточно проста — вместо того, чтобы создавать битовую строку для каждого отдельного значения свойства, весь диапазон значений делится на интервалы (bins), а битовая строка создается для каждого интервала. Например, битовые индексы для групп выглядят следующим образом: группа 0–11010010; группа 1–00000101; группа 2–00101000 (табл. 1). Помимо очевидного выигрыша по общему объему индексов, выигрыш в производительности достигается в том случае, если диапазон запроса по атрибуту полностью накрывает одну или несколько групп, — количество дизъюнкций битовых строк тогда сокращается до одного. Однако, помимо оптимального разбиения на группы, здесь возникает проблема, когда запрос лишь частично накрывает одну из групп и требуется дополнительная проверка для каждого значения из такой группы: удовлетворяет оно запросу или нет. Эта проблема получила название candidate checking, и для ее решения также предложено множество подходов. Но в целом, особенно с появлением хранилищ и озер данных, просто группирования, даже с всевозможными модификациями, оказалось недостаточно для достижения приемлемой производительности обработки запросов на больших базах данных. Продолжением концепции binning стали иерархические битовые индексы (Hierarchical Bitmap Indexes, HBI) — активно развивающееся сегодня направление оптимизации работы с базами данных.

Индексация времени

Время — величина, обладающая естественной иерархичностью, и существует множество единиц ее измерения, что ставит проектировщика перед задачей оптимального выбора. Представим CRM-систему с сущностью «Входящие звонки». Один из атрибутов — это время поступления звонка с точностью до секунды. Интенсивность поступления звонков в масштабах всей компании, эксплуатирующей СУБД, достаточна высока, таблица большая. Типичное приложение — генерация отчетов по звонкам с временным диапазоном в качестве фильтра (вывести информацию о звонках, поступивших в определенный период времени). Использование битовых индексов здесь означает, что для каждого значения времени, для которого зафиксирован хотя бы один звонок, создается битовая строка, возможно, состоящая из нескольких подстрок (chunks). При запросе берутся все имеющиеся индексы для значений, входящих в заданный диапазон, и путем их дизъюнкции вычисляется битовая строка, единицы которой соответствуют ID звонков, удовлетворяющих запросу и выводимых в итоговый отчет.

Зависимость трудоемкости обработки запроса от значения крупного индекса

Применение битовых индексов для промышленных объемов данных не дает приемлемой производительности — отчеты генерируются слишком медленно. Узкое место — количество индексов, подпадающих под условия фильтра запроса. При большом диапазоне запроса и высокой интенсивности занесения в базу новых записей возникает ощутимая задержка: все строки нужно загрузить в память и выполнить над ними дизъюнкцию. Какую выбрать иерархию для максимальной эффективности? Даже если предположить, что, помимо секундного (мелкого) индекса, имеется в наличии только один крупный, какому интервалу времени он должен соответствовать? Если крупный индекс выбрать слишком маленьким (скажем, две секунды), это может дать мизерный эффект (количество крупных индексов, необходимых для обслуживания запроса, может остаться практически тем же), а если слишком большим, он может оказаться бесполезен, если длина запроса в среднем меньше него. Ключевыми исходными данными для оптимизации являются две функции распределения вероятностей: занесения записей в базу и длины запроса. Зная распределения этих случайных величин, можно выбрать размер крупного индекса, минимизирующий среднее значение третьей случайной величины — общей суммы количества крупного и мелкого индексов, «накрываемых» запросом на входном потоке событий. Но, чтобы оптимизировать некоторую целевую функцию, нужно уметь ее вычислять — по двум распределениям и выбранной иерархии вычислить среднее число всех битовых индексов, необходимых для обслуживания запроса.

Решение этой задачи методами теории вероятностей предложено в [2], а представление о практическом «выхлопе» этого решения можно получить из рисунка. Новая запись в базе появлялась в среднем каждые 30 секунд (параметр экспоненциального распределения равен 0,033), а средняя длина интервала поискового запроса — 1000 секунд (параметр равен 0,001). На рисунке изображены зависимости среднего числа индексов от длины интервала для крупного индекса в случае одного крупного индекса (тонкая линия) и двух (толстая линия), где второй крупный индекс равен одному часу. Из графика видно, что минимум действительно существует, достигается примерно в диапазоне 345–350 секунд и равен 5,7 индекса для тонкой линии и 5,2 для толстой. В нулевой точке, когда отсутствует какая-либо иерархия, трудоемкость значительна, а применение HBI позволило получить прирост производительности как минимум в пять раз. Что и было подтверждено как при нагрузочном тестировании, так и в ходе промышленной эксплуатации CRM.

Иерархические индексы берут свое начало с работы [4] и были введены для выполнения запросов по атрибутам-множествам (Set-Valued Attributes), допустимых стандартом SQL3.

Рассмотрим таблицу Purchases (trans id, cust id, products), хранящую записи о покупках клиента. В таблице три поля: ID транзакции (покупки), ID клиента, купленные им продукты. Типовые запросы можно разделить на запрос подмножества (subset query), когда ищутся покупки, в состав которых входит заданный набор продуктов; запрос покрывающего множества (superset query), когда ищутся покупки, в состав которых входят покупки только из заданного множества; запрос подобия (similarity query), когда ищутся покупки, совпадающие с данным множеством с точностью до установленного порога подобия. Вот как мог бы выглядеть subset query на SQL для количества покупок с молоком и маслом:

SELECT COUNT (DISTINCT A.cust id)

FROM Purchases A, Purchases B

AND A.item = ‘milk’ AND B.item = ‘butter’;

Идея HBI состоит в том, чтобы пронумеровать все значения, которые могут быть элементами set-атрибута, и параметризовать его двумя числами: l — длина индексного узла, d — количество уровней иерархии. Тогда любое значение set-атрибута (некоторое множество) может быть представлено деревом битовых индексов. Такое представление позволяет свести выполнение запроса с условием по set-атрибуту к небольшому количеству эффективных логических операций над битовыми строками, равному d. Поясним это на примере subset-запроса. Пусть значение set-атрибута S= <2, 3, 9, 12, 13, 14, 38, 40>, l=4, d=3. Тогда это значение можно представить в виде дерева битовых индексов (табл. 2). На первом уровне находится единственный узел — корень (root node), на последнем — узлы-листья (leaf nodes), на остальных — внутренние узлы (inner nodes).

Номера позиций единиц в листьях соответствуют значениям элементов S (нумерация от единицы). Пустые узлы (empty nodes), состоящие только из нулей, — эти узлы не хранятся в виде индекса на диске. Пусть имеется запрос q= <9, 13, 40>. Используя индексное дерево для S, нужно определить, удовлетворяет множество этому запросу или нет.

Что означает создание индекса по иерархическому признаку

Связный список узлов для множества S — K (S) = <1010,1011,0100,0110,1001,1100, 0101>, для множества q K (q) = <1010,0011,0100,1000,1000,0001>. Конъюнкция корневых узлов дает K1 (q) =1010 — сравнение корневых узлов не противоречит тому, что множество S накрывает множество q. Далее продвигаемся по узлам первого уровня множества q. Один шаг вдоль уровня множества q может соответствовать нескольким шагам вдоль того же уровня множества S (множество S может включать элементы, не входящие в q). Конъюнкция K2 (S) =1011 и K2 (q) =0011 дает K2 (q), конъюнкция K3 (S) =0100 и K3 (q) =0100 дает K3 (q) — и на втором уровне проверка пройдена успешно. Начинаем проход по узлам третьего уровня множества q. Чтобы сопоставить первому из этих узлов, равному 1000, узел множества S, первый узел третьего уровня множества S 0110 нужно пропустить: он соответствует единице, стоящей на первой позиции узла второго уровня 1011, а этой единицы на втором уровне множества q нет — узел равен 0011. Поэтому конъюнкцию узла множества q 1000 осуществляем с узлом третьего уровня 1001 множества S. Она равна 1000 — пройдено. Нетрудно видеть, что оставшиеся две проверки также проходят. Таким образом, множество S запросу q удовлетворяет. Благодаря использованию HBI отпадает необходимость в использовании join, а трудоемкость выполнения запроса с условием по set-атрибуту становится логарифмической — это округленный в большую сторону логарифм максимального значения элемента set-атрибута по основанию l.

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

Идеи, высказанные в [3], в общем-то, очевидны, но тем не менее их должен был кто-то впервые заявить. Объектом изучения этой работы являются хранилища данных (data warehouses, весьма распространенный объект, когда речь идет о битовых индексах) и присущая им организация хранения данных, когда некую таблицу сущностей (fact table) сопровождает набор таблиц, хранящих все возможные значения атрибутов этих сущностей (dimension tables). Типовым запросом к такой таблице является звездчатый запрос (star query), требующий выборки записей из таблицы сущностей при наложении некоторых условий на значения различных атрибутов. Обычным способом выполнения таких запросов является операция соединения (join) между таблицей сущностей и каждой из таблиц атрибутов. Наличие у атрибута естественной иерархии позволяет построить для него каскад битовых индексов, ускоряющих выборку данных и избавляющих от необходимости выполнять join. Рассмотрим простой пример (табл. 3).

Что означает создание индекса по иерархическому признаку

Предположим, что в десяти записях таблицы сущностей значения атрибута «Продукт» следуют в заданном порядке, причем для этого атрибута имеется более высокий уровень иерархии — «Категории», для категории существует своя таблица (в данном случае из двух записей) и свои битовые индексы. В случае, когда диапазон запрашиваемых продуктов накрывает всю категорию, например «Ноутбуки», нет необходимости выполнять дизъюнкцию (логическое ИЛИ) для всех пяти битовых индексов этой категории — запрашиваемую выборку сразу дает битовый индекс «Ноутбуки». Более того, если в запросе требуется учесть только четыре из пяти продуктов категории, можно применить XOR (исключающее ИЛИ) над индексом по всей категории и индексом для продукта, не охваченного запросом. Это даст снижение количества дизъюнктов — битовых строк — с пяти до двух. В работе [3] этот подход был протестирован на большой базе данных аукционных продаж — быстродействие оказалось намного выше, чем в случае использования обычных битовых индексов Oracle.

Теория битовых индексов в целом и HBI в частности достигла уровня зрелости, позволяющего архитекторам баз данных делать осознанный выбор в пользу оптимального проектного решения и ставить разработчикам корректную задачу на расширение стандартного функционала битовых индексов для конкретной СУБД. Несмотря на то что для этого могут потребоваться дополнительные исследования и более детальное изучение нюансов задачи, результат в виде кратного повышения производительности этого стоит.

Илья Труб ( itrub@yandex.ru ) — ведущий инженер-программист, Исследовательский центр Samsung (Москва). Статья подготовлена на основе материалов выступления автора на конференции « Технологии управления данными 2018 ».

Поделитесь материалом с коллегами и друзьями

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Что означает создание индекса по иерархическому признаку