Какой хороший баланс решить, когда разделить таблицу в BigQuery? - PullRequest
5 голосов
/ 07 ноября 2019

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

SELECT  sum(score) 
FROM `fh-bigquery.stackoverflow_archive.201906_posts_questions` 
WHERE creation_date > "2019-01-01" 

Занимает 1 секунду и обрабатывает 270,7 МБ.

То же самое, с разделами:

SELECT  sum(score) 
FROM `temp.questions_partitioned` 
WHERE creation_date > "2019-01-01"

Занимает 2 секунды и обрабатывает 14,3 МБ.

Таким образом, мы видим преимущество в обработке МБ, но запрос выполняется медленнее.

Какая хорошая стратегия для решения, когда разделить?

(из полученного мной электронного письма). сегодня)

1 Ответ

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

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

В этом случае таблица, используемая для теста, содержит 1,6 ГБ данных на 2019 год (до июня вэтот). Это 1,6 ГБ / 180 = 9 МБ данных для каждого ежедневного раздела.

Для такого небольшого объема данных - его размещение в ежедневных разделах не принесет больших преимуществ. Вместо этого рассмотрите возможность разделения данных по годам. См. Следующий вопрос, чтобы узнать, как:

Другойальтернативой не является разбиение таблицы вообще, а использование кластеризации для сортировки данных по дате. Тогда BigQuery может выбрать идеальный размер каждого блока.

Если вы хотите запустить собственные тесты, сделайте следующее:

CREATE TABLE `temp.questions_partitioned`
PARTITION BY DATE(creation_date)
AS
SELECT *
FROM `fh-bigquery.stackoverflow_archive.201906_posts_questions` 

без разделов, просто кластеризация по дате:

CREATE TABLE `temp.questions_clustered`
PARTITION BY fake_date
CLUSTER BY creation_date
AS

SELECT *, DATE('2000-01-01') fake_date  
FROM `fh-bigquery.stackoverflow_archive.201906_posts_questions` 

Тогда мой запрос к кластерной таблице будет:

SELECT sum(score) 
FROM `temp.questions_clustered`
WHERE creation_date > "2019-01-01" 

И это заняло 0,5 секунды, обработано 17 МБ.

По сравнению:

  • Необработанный стол: 1 с, 270,7 МБ
  • С разделами: 2 с, 14,3 МБ
  • Сгруппировано: 0,5 с, 17 МБ

У нас есть победитель! Кластеризация организовала ежедневные данные (что не так много для этой таблицы) в более эффективные блоки, чем строго разделив их по дням.

Интересно также посмотреть подробности выполнения для каждого запроса в этих таблицах:

Потребляемое время слота

  • Необработанный стол: 10,683 сек
  • Разделение: 7,308 сек
  • Кластеризация: 0,718 сек

Как видите, в запросе к необработанной таблице использовалось много слотов (параллелизм), чтобы получить результаты за 1 секунду. В этом случае 50 рабочих обработали всю таблицу с данными за несколько лет, прочитав 17,7 млн ​​строк. Запрос к многораздельной таблице должен был использовать много слотов, но это потому, что каждому слоту были назначены небольшие ежедневные разделы, чтение, которое использовало 153 параллельных рабочих на 0,9 млн строк. Вместо этого кластерный запрос мог использовать очень небольшое количество слотов. Данные были хорошо организованы для чтения 57 параллельными работниками, которые читали 1,12 млн строк.

enter image description here

enter image description here

enter image description here

См. Также:

...