Проблемы с производительностью снежинки при запросе больших таблиц - PullRequest
0 голосов
/ 05 ноября 2019

Я пытаюсь запросить таблицу, в которой есть 1 ТБ данных, сгруппированных по дате и компании. Простой запрос занимает много времени

Отправка запроса и профиля запроса

SELECT
    sl.customer_code,
    qt_product_category_l3_sid,
    qt_product_brand_sid,
    sl.partner_code,
    sl.transaction_id,
    dollars_spent,
    units,
    user_pii_sid,
    promo_flag,
    media_flag
FROM 
    cdw_dwh.public.qi_sg_promo_media_sales_lines_fact sl
WHERE  
    transaction_date_id >= (to_char(current_date - (52*7) , 'yyyymmdd')  ) 
    AND sl.partner_code IN ('All Retailers')
    AND qt_product_category_l3_sid IN (SELECT DISTINCT qt_product_category_l3_sid 
                                       FROM cdw_dwh.PUBLIC.qi_sg_prompt_category_major_brand 
                                       WHERE qt_product_category_l1_sid IN (246))
                                         AND qt_product_brand_sid IN (SELECT qt_product_brand_sid 
                                                                      FROM cdw_dwh.PUBLIC.qi_sg_prompt_category_major_brand 
                                                                      WHERE qt_product_major_brand_sid IN (246903, 430138))

введите описание изображения здесь

Ответы [ 3 ]

0 голосов
/ 07 ноября 2019

99% времени было потрачено на сканирование таблицы. Фильтры в запросе не соответствуют вашим ключам кластеризации, поэтому это не сильно поможет. В зависимости от того, сколько исторических данных у вас есть в этой таблице и будете ли вы продолжать читать данные за год, вам может быть лучше (или создать материализованное представление) кластеризацию с помощью qt_product_brand_sid или qt_product_category_l3_sid, в зависимости от того, какой из них будетфильтрация данных быстрее.

0 голосов
/ 07 ноября 2019

Большое изменение требует изменения структуры данных даты транзакции на поле истинной даты против varchar.

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

0 голосов
/ 05 ноября 2019

«простой запрос» Я не уверен, что такая вещь существует. Наивный запрос, конечно.

select * from really_large_table where column1 = value;

будет работать очень плохо, если вы заботитесь только о 1 или 2 столбцах. Так как снежинка должна загружать все данные. Вы получите улучшение отношения данных столбца к строке, используя

select column1, column2 from really_large_table where column1 = value;

, теперь только два столбца данных необходимо прочитать из хранилища данных.

Возможновы ищете данные, значение которых равно > 100, потому что вы думаете, что этого не должно произойти. Тогда

select column1, column2 from really_large_table where column1 > 100 limit 1;

будет работать намного лучше, чем

select column1, column2 from really_large_table order by column1 desc limit 50;

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

Еще одна вещь, на которую следует обратить внимание в связи с тем, что иногда ваши вычисления могут создавать слишком много промежуточного состояния, и это "внешние разливы" (точная формулировка неверна), которые очень похожи на исчерпание памяти и переход на замену диска.

Тогда мы увидели нехватку памяти, когда выполняли слишком много работы в JavaScript UDF, что замедлило процесс.

Но большинство из них можно обнаружить, посмотрев профиль запроса и посмотрев нагорячие точки.

...