Ограничения в использовании всех строковых столбцов в BigQuery - PullRequest
2 голосов
/ 07 июня 2019

У меня есть входная таблица в BigQuery, в которой все поля хранятся в виде строк. Например, таблица выглядит так:

name      dob             age     info
"tom"     "11/27/2000"    "45"    "['one', 'two']"

И в запросе я сейчас делаю следующее

WITH
  table AS (
  SELECT
    "tom" AS name,
    "11/27/2000" AS dob,
    "45" AS age,
    "['one', 'two']" AS info )
SELECT
  EXTRACT( year from PARSE_DATE('%m/%d/%Y', dob)) birth_year,
  ANY_value(PARSE_DATE('%m/%d/%Y', dob)) bod,
  ANY_VALUE(name) example_name,
  ANY_VALUE(SAFE_CAST(age AS INT64)) AS age
FROM
  table
GROUP BY
  EXTRACT( year from PARSE_DATE('%m/%d/%Y', dob))

Кроме того, я попытался выполнить очень простую операцию group by, приводящую элемент к строке, а не нет, и я не увидел никакого снижения производительности в наборе данных ~ 1M строк (на самом деле, в данном конкретном случае, приведение чтобы строка была быстрее):

enter image description here

Помимо плохой практики "хранить" эту таблицу, состоящую из всех строк, и не преобразовывать ее в ее правильный тип, с какими ограничениями (функциональными или с точки зрения производительности) я столкнусь, сохраняя все таблицы -строка вместо того, чтобы хранить его как свой собственный тип. Я знаю, что будет небольшое увеличение размера из-за хранения строк вместо number / date / bool / и т. Д., Но с какими основными ограничениями или сбоями в производительности я столкнусь, если буду так держать?

Вне головы, единственные ограничения, которые я вижу:

  • Запросы станут более сложными (хотя на самом деле не имеет значения, если использовать построитель запросов).
  • Немного сложнее извлечь не строковые элементы из полей массива.
  • Вставка данных становится немного сложнее (например, необходимо следить за форматом даты).

Но все это кажется очень маленькими предметами, которые можно обойти. Существуют ли другие, более «серьезные» причины, по которым использование всех строковых полей было бы огромным ограничением, либо в ограничении возможностей запросов, либо в огромных падениях производительности в различных случаях?

Ответы [ 5 ]

3 голосов
/ 12 июня 2019

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

Тем временем,

хотя это не имеет большого значения, если использовать построитель запросов ...

на основе приведенной выше выдержки - я хотел бы затронуть некоторые аспекты этого подхода (сохранение всех в виде строк)

В то время как мы обычно заботились о CASTing из строки в собственный тип для применения соответствующих функций и т. Д., Я понял, что для создания сложного и универсального запроса с каким-то видом компоновщика запросов в некоторых случаях требуется обратное приведение собственного типа к строке для применения функции как STRING_AGG [просто] как быстрый пример

Итак, мои мысли:

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

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

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

Примечание: ваш вопрос довольно широк и основан на мнениях (что, кстати, не очень уважается в SO), поэтому, очевидно, мой ответ - полностью мое мнение, но основано на довольно большом опыте с BigQuery

0 голосов
/ 15 июня 2019

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

И если кто-то решил построить слой между этими данными и инструментом отчетности, который преобразовал все данные, то вы также можете просто сделать это один раз для таблицы / данных и покончить с этим.

0 голосов
/ 13 июня 2019

Это нормально, что с меньшим количеством столбцов / строк вы не чувствуете проблем. Вы начинаете чувствовать проблемы, когда ваши данные становятся огромными.

Основные проблемы:

  • Обслуживание кода: подумайте о будущих требованиях, которые вы можете получить. Каждое преобразование для манипулирования данными добавит дополнительную сложность вашему коду. Например, если ваш клиент просит вывести подростков в будущем, вам нужно преобразовать строку в дату, чтобы получить возраст, а затем иметь возможность выполнить манипуляцию.

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

  • Производительность чтения: если у вас есть больше байтов для чтения в огромных таблицах, это потребует значительных затрат времени. Например, обычно операторы телефонной связи имеют несколько миллиардов строк данных в месяц.

  • Если сложность вашего кода возрастет, вам нужно будет повторить конверсии в нескольких местах.

Даже один из вышеперечисленных пунктов должен толкать один на расстояние от использования строк для всего.

0 голосов
/ 12 июня 2019

Вы в порядке, чтобы хранить строку "33/02/2000" в качестве даты в одной строке и "21st of December 2012" в другой строке и "22ое октября 2013" в другой строке?

Вы в порядке, чтобы хранить строку "45" как возраст в одной строке и "young" в другой строке?

Вы в порядке, когда возраст "10" меньше, чем возраст "9"?

Типы данных предоставляют некоторый базовый механизм проверки данных на уровне базы данных.


Есть ли у баз данных BigQuery понятие индексов?

Если да, то, скорее всего, эти индексы станут бесполезными, как только вы начнете приводить свои строки к нужным типам, таким как

SELECT 
    ...
WHERE 
    age > 10 and age < 30

против

SELECT 
    ...
WHERE 
    ANY_VALUE(SAFE_CAST(age AS INT64)) > 10 
    and ANY_VALUE(SAFE_CAST(age AS INT64)) < 30
0 голосов
/ 07 июня 2019

Вы можете столкнуться с некоторыми проблемами с производительностью и хранилищем, вы можете найти некоторые рекомендации в официальной документации .

Я думаю, что основная проблема с производительностью будет связана с операцией CAST, помнитечто BigQuery Engine будет иметь дело с операцией CAST для каждого значения для каждой строки.Чтобы показать, что операции Compute, давайте возьмем простой запрос:

SELECT
  street_number
FROM
  `bigquery-public-data.austin_311.311_service_requests`
LIMIT
  5000

Затем мы проверяем этапы, выполненные в выполнении, подробно, и видим следующее:

READ    
       $1:street_number
       FROM bigquery-public-data.austin_311.311_service_requests
LIMIT   
       5000
WRITE   
       $1
       TO __stage00_output

ТолькоТребуются операции чтения, ограничения и записи.Однако если мы выполним тот же запрос, добавив операцию приведения.

SELECT
  CAST(street_number AS int64)
FROM
  `bigquery-public-data.austin_311.311_service_requests`
LIMIT
  5000

Мы видим, что для приведения значения также требуется операция вычисления:

READ    
       $1:street_number
       FROM bigquery-public-data.austin_311.311_service_requests
LIMIT   
       5000
COMPUTE 
       $10 := CAST($1 AS INT64)
WRITE   
       $10
TO __stage00_output

Это очевидночто если вы сделаете инструкцию приведения, для этого потребуется операция Compute.Эти вычислительные операции могут занимать некоторое время, что может вызвать проблемы при увеличении размера операции.

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

И, наконец, ссылаясь на производительность хранилища, как вы упомянули, строки не имеют фиксированного размера, и это может привести к увеличению размера.

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