Ускорение соединений с сохранением кардинальности
Эта тема описывает, как ускорить соединения с сохранением кардинальности с помощью обрезки таблиц. Эта функция поддерживается начиная с версии 1.5.0.
Обзор
Соединение с сохранением кардинальности гарантирует, что кардинальность и коэффициент дублирования выходных строк остаются такими же, как у одной из входных таблиц в соединении. Рассмотрим следующие примеры:
-
Inner Join:
SELECT A.* FROM A INNER JOIN B ON A.fk = B.pk;В этом случае
A.fk(внешний ключ) НЕ NULL и ссылается наB.pk(первичный ключ). Каждая строка вAсоответствует точно одной строке вB, поэтому кардинальность и коэффициент дублирования выходных данных соответствуют таковым уA. -
Left Join:
SELECT A.* FROM A LEFT JOIN B ON A.fk = B.pk;Здесь
A.fkссылается наB.pk, ноA.fkможет содержать значения NULL. Каждая строка вAсоответствует максимум одной строке вB. В результате кардинальность и коэффициент дублирования выходных данных остаются согласованными сA.
В таких типах соединений, если финальные выходные столбцы зависят только от столбцов таблицы A, а столбцы из таблицы B не используются, таблица B может быть обрезана из соединения. Начиная с версии 1.5.0, Selena поддерживает обрезку таблиц в соединениях с сохранением кардинальности, которая может происходить в общих табличных выражениях (CTE), логических представлениях и подзапросах.
Случай использования: выбор признаков в реальном времени для контроля рисков
Функция обрезки таблиц для соединений с сохранением кардинальности особенно полезна в сценариях, таких как выбор признаков в реальном времени для контроля рисков. В этом контексте пользователям необходимо выбирать данные из большого количества таблиц, часто имея дело с комбинаторным взрывом столбцов и таблиц. Следующие ха рактеристики распространены в области контроля рисков:
- Многочисленные признаки распределены по множеству независимо обновляемых таблиц.
- Свежие данные должны быть видимыми и запрашиваемыми в реальном времени.
- Плоское логическое представление используется для упрощения модели данных, делая SQL для извлечения столбцов более лаконичным и продуктивным.
Использование плоского логического представления, а не других ускоренных слоев данных, помогает пользователям эффективно получать доступ к данным в реальном времени. В каждом запросе извлечения столбцов требуется соединить только несколько таблиц (не все таблицы в логическом представлении). Обрезая неиспользуемые таблицы из этих запросов, вы можете уменьшить количество соединений и улучшить производительность.
Поддержка функции
Функция обрезки таблиц поддерживает многотабличные соединения как в схеме звезды, так и в схеме снежинки. Многотабличные соединения могут появляться в CTE, логических представлениях и подзапросах, обеспечивая более эффективное выполнение запросов.
В настоящее время функция обрезки таблиц поддерживается только для OLAP таблиц и облачных таблиц. Внешние таблицы в многотабличных соединениях не могут быть обрезаны.
Использование
Следующие примеры используют набор данных TPC-H.
Предварительные условия
Для использования функции обрезки таблиц должны быть выполнены следующие условия:
- Включить обрезку таблиц
- Установить ключевые ограничения
Включение обрезки таблиц
По умолчанию обрезка таблиц отключена. Вам необходимо включить эту функцию, настроив следующие переменные сессии:
-- Включить обрезку таблиц на фазе RBO.
SET enable_rbo_table_prune=true;
-- Включить обрезку таблиц на фазе CBO.
SET enable_cbo_table_prune=true;
-- Включить обрезку таблиц на фазе RBO для оператора UPDATE на таблицах с первичным ключом.
SET enable_table_prune_on_update = true;
Установка ключевых ограничений
Таблицы, подлежащие обрезке, должны иметь ограничения Unique Key или Primary Key, по крайней мере, в LEFT или RIGHT соединениях. Для обрезки таблиц в INNER JOIN вы должны определить ограничения Foreign Key в дополнение к ограничениям Unique Key или Primary Key.
Таблицы Primary Key и Unique Key имеют свои неявные ограничения Primary Key или Unique Key, естественно встроенные в них. Однако для таблиц Duplicate Key вы должны вручную определить ограничения Unique Key и убедиться, чт о дублирующиеся строки не существуют. Обратите внимание, что Selena не принудительно применяет ограничения Unique Key к таблицам Duplicate Key. Вместо этого она рассматривает их как подсказки для оптимизации для более агрессивного планирования запросов.
Пример:
-- Определить ограничение Unique Key при создании таблицы.
CREATE TABLE `lineitem` (
`l_orderkey` int(11) NOT NULL COMMENT "",
`l_partkey` int(11) NOT NULL COMMENT "",
`l_suppkey` int(11) NOT NULL COMMENT "",
`l_linenumber` int(11) NOT NULL COMMENT "",
`l_quantity` decimal64(15, 2) NOT NULL COMMENT "",
`l_extendedprice` decimal64(15, 2) NOT NULL COMMENT "",
`l_discount` decimal64(15, 2) NOT NULL COMMENT "",
`l_tax` decimal64(15, 2) NOT NULL COMMENT "",
`l_returnflag` varchar(1) NOT NULL COMMENT "",
`l_linestatus` varchar(1) NOT NULL COMMENT "",
`l_shipdate` date NOT NULL COMMENT "",
`l_commitdate` date NOT NULL COMMENT "",
`l_receiptdate` date NOT NULL COMMENT "",
`l_shipinstruct` varchar(25) NOT NULL COMMENT "",
`l_shipmode` varchar(10) NOT NULL COMMENT "",
`l_comment` varchar(44) NOT NULL COMMENT ""
) ENGINE=OLAP
DUPLICATE KEY(`l_orderkey`,`l_partkey`, `l_suppkey`)
DISTRIBUTED BY HASH(`l_orderkey`) BUCKETS 96
PROPERTIES (
"unique_constraints" = "l_orderkey,l_linenumber"
);
-- Или вы можете определить ограничение Unique Key после создания таблицы.
ALTER TABLE lineitem SET ("unique_constraints" = "l_orderkey,l_linenumber");
Ограничения Foreign Key, с другой стороны, должны быть определены явно. Подобно ограничениям Unique Key для таблиц Duplicate Key, ограничения Foreign Key действуют как подсказки для оптимизатора. Selena не принудительно применяет согласованность ограничений Foreign Key. Вы должны обеспечить целостность данных при производстве и загрузке данных в Selena.
Пример:
-- Создать таблицу, на которую будет ссылаться ограничение Foreign Key.
-- Обратите внимание, что столбец, на который ссылаются, должен иметь ограничения Unique Key или Primary Key.
-- В этом примере `p_partkey` является первичным ключом таблицы `part`.
CREATE TABLE part (
p_partkey int(11) NOT NULL,
p_name VARCHAR(55) NOT NULL,
p_mfgr CHAR(25) NOT NULL,
p_brand CHAR(10) NOT NULL,
p_type VARCHAR(25) NOT NULL,
p_size INT NOT NULL,
p_container CHAR(10) NOT NULL,
p_retailprice DOUBLE NOT NULL,
p_comment VARCHAR(23) NOT NULL
) ENGINE=OLAP
PRIMARY KEY(`p_partkey`)
DISTRIBUTED BY HASH(`p_partkey`) BUCKETS 12;
-- Определить ограничение Foreign Key при создании таблицы.
CREATE TABLE `lineitem` (
`l_orderkey` int(11) NOT NULL COMMENT "",
`l_partkey` int(11) NOT NULL COMMENT "",
`l_suppkey` int(11) NOT NULL COMMENT "",
`l_linenumber` int(11) NOT NULL COMMENT "",
`l_quantity` decimal64(15, 2) NOT NULL COMMENT "",
`l_extendedprice` decimal64(15, 2) NOT NULL COMMENT "",
`l_discount` decimal64(15, 2) NOT NULL COMMENT "",
`l_tax` decimal64(15, 2) NOT NULL COMMENT "",
`l_returnflag` varchar(1) NOT NULL COMMENT "",
`l_linestatus` varchar(1) NOT NULL COMMENT "",
`l_shipdate` date NOT NULL COMMENT "",
`l_commitdate` date NOT NULL COMMENT "",
`l_receiptdate` date NOT NULL COMMENT "",
`l_shipinstruct` varchar(25) NOT NULL COMMENT "",
`l_shipmode` varchar(10) NOT NULL COMMENT "",
`l_comment` varchar(44) NOT NULL COMMENT ""
) ENGINE=OLAP
DUPLICATEK KEY(`l_orderkey`,`l_partkey`, `l_suppkey`)
DISTRIBUTED BY HASH(`l_orderkey`) BUCKETS 96
PROPERTIES (
"foreign_key_constraints" = "(l_partkey) REFERENCES part(p_partkey)"
);
-- Или вы можете определить ограничение Foreign Key после создания таблицы.
ALTER TABLE lineitem SET ("foreign_key_constraints" = "(l_partkey) REFERENCES part(p_partkey)");
Обрезка таблиц в LEFT/RIGHT соединениях на основе уникальных или первичных ключей
Обрезка таблиц в LEFT или RIGHT соединениях не требует, чтобы сохраняемая сторона соединения имела внешний ключ, ссылающийся на обрезаемую сторону. Это делает обрезку более гибкой и надежной, даже если целостность ссылок не может быть гарантирована.
Обрезка в LEFT/RIGHT соединениях на основе уникальных или первичных ключей имеет менее строгие требования по сравнению с обрезкой INNER JOIN на основе внешних ключей.
Условия для обрезки:
-
Обрезаемая сторона
Обрезаемая таблица должна быть правой стороной в LEFT JOIN или левой стороной в RIGHT JOIN.
-
Условия соединения
Соединение должно использовать только условия равенства (
=), а соединяемые столбцы обрезаемой стороны должны быть надмножеством уникальных или первичных ключей. -
Выходные столбцы
Должны выводиться только столбцы сохраняемой стороны, и результат должен поддерживать ту же кардинальность и коэффициент дублирования, что и сохраняемая сторона.
-
NULL/значения по умолчанию
Соединяемые столбцы в сохраняемой стороне