Соединение BigQuery слишком медленное для маленького стола - PullRequest
0 голосов
/ 05 июня 2018

У меня есть таблица со следующими данными:
- Размер таблицы 39,6 МБ
- Количество строк 691 562
- 2 столбца: contact_guid STRING, program_completed STRING
- тип данных столбца 1 подобенUUIDоколо 30 символов длины
- тип данных столбца 2 - строка длиной около 50 символов

Я пытаюсь выполнить этот запрос:

#standardSQL
SELECT
  cp1.contact_guid AS p1,
  cp2.contact_guid AS p2,
  COUNT(*) AS cnt
FROM
  `data.contact_pairs_program_together`  cp1
JOIN
  `data.contact_pairs_program_together`  cp2
ON
  cp1.program_completed=cp2.program_completed
WHERE
  cp1.contact_guid < cp2.contact_guid
GROUP BY
  cp1.contact_guid,
  cp2.contact_guid having cnt >1 order by cnt desc

Время выполнения: 1200 секунд

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

Мои вопросы:

  1. Я чувствую этот размер таблицы вТермины mb слишком малы для BigQuery, поэтому, почему это занимает так много времени?А что означает маленькая таблица для BigQuery в контексте объединения с точки зрения количества строк и размера в байтах?
  2. Не слишком ли большое количество строк?700k ^ 2 - это 10 ^ 11 строк во время соединения.Каким было бы реалистичное количество строк для объединений?
  3. Я проверил документацию относительно объединений, но не нашел много информации о том, насколько большой может быть таблица для объединений и сколько времени можно ожидать для ее выполнения.,Как мы оцениваем приблизительное время выполнения?

Детали выполнения: enter image description here enter image description here

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Согласитесь с приведенными ниже предложениями

посмотрите, сможете ли вы перефразировать ваш запрос, используя аналитические функции (Тим)

Использование аналитических функций было бы намного лучшеидея (автор Эллиотта)

Ниже я хотел бы изложить, как это сделать

#standardSQL
SELECT
  p1, p2, COUNT(1) AS cnt
FROM (
  SELECT
    contact_guid AS p1, 
    ARRAY_AGG(contact_guid) OVER(my_win) guids
  FROM `data.contact_pairs_program_together` 
  WINDOW my_win AS (
    PARTITION BY program_completed 
    ORDER BY contact_guid DESC 
    RANGE BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
  )
), UNNEST(guids) p2
GROUP BY p1, p2
HAVING cnt > 1
ORDER BY cnt DESC   

Пожалуйста, попробуйте и дайте нам знать, если это помогло

0 голосов
/ 05 июня 2018

Как показано на скриншоте, который вы предоставили - вы имеете дело с разрывным соединением.

В этом случае шаг 3 занимает 1,3 миллиона строк и дает 459 миллионов строк.Шаги с 04 по 0B связаны с перераспределением и перестановкой всех этих дополнительных данных - поскольку запрос не предоставил достаточно ресурсов для обработки такого количества строк: он увеличен с 1 параллельного ввода до 10 000!

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

Как насчет того, чтобы сгенерировать все дополнительные строки в одной операции (выполнить объединение, материализоваться), а затем запустить другой запрос для обработки 459 миллионов строк?Первый запрос будет медленным по объясненным причинам, но второй будет выполняться быстро, поскольку BigQuery выделит достаточно ресурсов для обработки такого количества данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...