#teradata
Вопрос:
Я пытаюсь создать представление, позволяющее эффективно развернуть большую таблицу с несколькими сотнями миллионов строк, т. Е. Преобразовать таблицу из широкого формата со множеством столбцов в длинный формат. Система-Teradata Vantage 16.20.
Исходная таблица имеет следующую структуру:
CREATE MULTISET TABLE my_table ( event_id BIGINT, -- a surrogate primary key event_date DATE, -- used for partitioning event_timestamp TIMESTAMP(6), -- timestamp used for analysis value_001 INTEGER, -- value nr. 1 used for analysis value_002 INTEGER, value_003 INTEGER, value_004 INTEGER, value_005 INTEGER, value_006 INTEGER, value_007 INTEGER, value_008 INTEGER, value_009 INTEGER, value_010 INTEGER, value_011 INTEGER, value_012 INTEGER, value_013 INTEGER, value_014 INTEGER, value_015 INTEGER, value_016 INTEGER, value_017 INTEGER, value_018 INTEGER, value_019 INTEGER, value_020 INTEGER -- value nr. 20 used for analysis ) PRIMARY INDEX ( event_id ) PARTITION BY RANGE_N(event_date BETWEEN '2020-01-01' AND '2025-12-31' EACH INTERVAL '1' DAY );
Исходная таблица разделена на разделы, event_date
чтобы обеспечить эффективные запросы для небольших диапазонов дат, например WHERE event_date BETWEEN DATE '2021-01-01' AND DATE '2021-01-02'
. Результат запроса должен содержать 20 строк на строку my_table
, каждая из которых содержит значение из одного из value_xx
столбцов my_table
.
Чтобы открепить таблицу, я использую следующий запрос:
WITH input_data AS ( SELECT * FROM my_table WHERE (1=1) -- AND event_date BETWEEN DATE '2021-01-01' AND DATE '2021-01-02' -- FILTER AT POSITION 1 ) SELECT event_id , event_date , seqnum , val FROM TD_UNPIVOT( ON (SELECT * FROM input_data) USING VALUE_COLUMNS('val') UNPIVOT_COLUMN('seqnum') COLUMN_LIST('value_001','value_002','value_003','value_004','value_005','value_006','value_007','value_008','value_009','value_010','value_011','value_012','value_013','value_014','value_015','value_016','value_017','value_018','value_019','value_020') COLUMN_ALIAS_LIST('001','002','003','004','005','006','007','008','009','010','011','012','013','014','015','016','017','018','019','020') ) t WHERE (1=1) -- AND event_date BETWEEN DATE '2021-01-01' AND DATE '2021-01-02' -- FILTER AT POSITION 2 ;
Когда фильтр даты активирован (без комментариев) в ПОЗИЦИИ 1 в примере кода, запрос завершается через несколько секунд. План объяснения показывает, что разделы my_table используются для эффективной фильтрации данных.
Когда фильтр даты активирован (без комментариев) только в ПОЗИЦИИ 2 в примере кода, запрос выполняется намного дольше и использует на порядок больше времени AMPCPUTime. План объяснения показывает , что все строки my_table обрабатываются TD_UNPIVOT
, т. е. разделение не используется для доступа к данным. Это очень неэффективно для больших исходных таблиц.
Когда я помещаю этот код в представление, фильтр в ПОЗИЦИИ 1 непригоден для использования, поскольку диапазон дат будет жестко задан в логике представления. Фильтрация во время доступа к просмотру ( SELECT ... FROM my_view WHERE event_date...
) приводит к неэффективной обработке, аналогичной фильтру в ПОЗИЦИИ 2. Я тоже попробовал UNPIVOT
вместо TD_UNPIVOT
этого , с тем же результатом.
Есть ли способ помочь планировщику запросов распространить фильтрацию с помощью операции unpivot на доступ к исходной таблице? С другими, гораздо более сложными аналитическими запросами , но без TD_UNPIVOT
них, это обычно работает довольно хорошо.
Комментарии:
1. Серьезное предположение здесь, но что произойдет, если вы прокомментируете это в CTE и в unpivot, где, и добавите это так:
FROM TD_UNPIVOT ( ON (SELECT * FROM INPUT_DATA WHERE DATE ...
2. @Andrew фильтрация только внутри
FROM TD_UNPIVOT ( ON (SELECT * FROM INPUT_DATA WHERE event_date ...
успешно использует разделение так же, как это делает фильтр в ПОЗИЦИИ 1. На самом деле, весь CTEinput_data
может быть устранен таким образом. Тем не менее, это все равно приведет к жестко заданному диапазону дат в представлении, которое я пытаюсь создать.3. О, вы, должно быть, пытаетесь создать представление о неживом. Я думал, вы пытаетесь создать представление, чтобы устранить CTE. Вот что я получаю за ответы на вопросы в понедельник утром…