Как объединить тысячу таблиц в наборе данных BigQuery? - PullRequest
0 голосов
/ 25 октября 2019

У меня есть набор данных в BigQuery с примерно 1000 таблицами, по одной для каждой переменной. Каждая таблица содержит два столбца: наблюдение_номер, переменная_имя. Обратите внимание, что столбец variable_name предполагает фактическое имя переменной. Каждая таблица содержит не менее 20000 строк. Каков наилучший способ объединения этих таблиц по номеру наблюдения?

Я разработал код Python, который будет выполняться в облачной функции, и генерирует SQL-запрос для объединения таблиц. Это достигается путем подключения к набору данных и циклического перемещения по таблицам, чтобы получить все table_ids. Однако запрос оказывается слишком большим, а производительность не такой высокой.

Вот пример кода Python, который генерирует запрос (имейте в виду, что он все еще выполняется локально, но еще не в облачной функции).

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set project_id and dataset_id.
project_id = 'project-id-gcp'
dataset_name = 'sample_dataset'
dataset_id = project_id+'.'+dataset_name

dataset = client.get_dataset(dataset_id)

# View tables in dataset
tables = list(client.list_tables(dataset))  # API request(s)
table_names = []

if tables:
    for table in tables:
        table_names.append(table.table_id)
else:
    print("\tThis dataset does not contain any tables.")

query_start = "select "+table_names[0]+".observation"+","+table_names[0]+"."+table_names[0]
query_select = ""
query_from_select = "(select observation,"+table_names[0]+" from `"+dataset_name+"."+table_names[0]+"`) "+table_names[0]
for table_name in table_names:
    if table_name != table_names[0]:
        query_select = query_select + "," + table_name+"."+table_name
        query_from_select = query_from_select + " FULL OUTER JOIN (select observation," + table_name + " from " + "`"+dataset_name+"."+table_name+"`) "+table_name+" on "+table_names[0]+".observation="+table_name+".observation"
query_from_select = " from ("+query_from_select + ")"
query_where = " where " + table_names[0] + ".observation IS NOT NULL"
query_order_by = " order by observation"

query_full = query_start+query_select+query_from_select+query_where+query_order_by

with open("query.sql","w") as f:
    f.write(query_full)

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

select 
  VARIABLE1.observation, 
  VARIABLE1.VARIABLE1, 
  VARIABLE2.VARIABLE2 
from 
  (
    (
      select 
        observation, 
        VARIABLE1 
      from 
        `sample_dataset.VARIABLE1`
    ) VARIABLE1 FULL 
    OUTER JOIN (
      select 
        observation, 
        VARIABLE2 
      from 
        `sample_dataset.VARIABLE2`
    ) VARIABLE2 on VARIABLE1.observation = VARIABLE2.observation
  ) 
where 
  VARIABLE1.observation IS NOT NULL 
order by 
  observation

По мере увеличения количества таблиц этот запрос становится все больше и больше. Любые предложения о том, как улучшить производительность этой операции? Есть ли другой способ решения этой проблемы?

1 Ответ

1 голос
/ 25 октября 2019

Я не знаю, есть ли хороший технический ответ на этот вопрос. Похоже, что вы пытаетесь выполнить огромное количество объединений в одном запросе, и сила BQ не реализована во многих объединениях.

Хотя ниже я обрисую потенциальное решение, рассмотрели ли вы, почемунужна таблица с 1000+ потенциальных столбцов? Не говорю, что вы этого не сделали, но могут быть альтернативные способы решения вашей проблемы без создания такой сложной таблицы.

Одним из возможных решений является разбиение ваших объединений / таблиц на более управляемые куски. Например, если у вас есть 1000 таблиц, запустите ваш скрипт для меньших подмножеств ваших таблиц (2/5/10 / и т. Д.) И запишите эти результаты в промежуточные таблицы. Тогда присоединяйтесь к своим промежуточным столам. Это может занять несколько слоев промежуточных таблиц в зависимости от размера ваших вложенных таблиц. По сути, вы хотите минимизировать (или сделать разумным) количество объединений в каждом запросе. После завершения удалите промежуточные таблицы, чтобы избежать ненужных расходов на хранение.

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