У меня есть рабочий хранилище данных MySQL, которое организовано как звездная схема, и я использую Talend Open Studio для интеграции данных 5.1 для создания процесса ETL. Я бы хотел, чтобы этот процесс выполнялся один раз в день. Я предположил, что одна из таблиц измерений (dimUser) будет содержать около 2 миллионов записей и 23 столбца.Data Warehouse ETL медленный - изменить первичный ключ в измерении?
Я создал небольшой тестовый процесс ETL в Talend, который сработал, но учитывая объем данных, который может потребоваться обновлять каждый день, текущая производительность не сократит его. Процесс ETL занимает четыре минуты, чтобы ОБРАТИТЬ или ВСТАВИТЬ 1000 записей в dimUser. Если бы я предполагал линейную зависимость между количеством записей и количеством времени для ОБНОВЛЕНИЯ или ВСТАВКИ, то ETL не может закончить через 3-4 часа (моя надежда), не говоря уже о одном дне.
Поскольку я не знаком с Java, я написал ETL как скрипт Python и столкнулся с той же проблемой. Хотя, я обнаружил, что если бы я сделал только INSERT, процесс шел намного быстрее. Я уверен, что узкое место вызвано операциями UPDATE.
Первичный ключ в dimUser является целым числом с автоматическим приращением. Мой друг предложил мне отказаться от этого первичного ключа и заменить его на первичный ключ с несколькими полями (в моем случае 2-3 поля).
Перед тем, как копировать тестовые данные из моего склада и изменить схему, может кто-нибудь представить предложения или руководящие принципы, связанные с
- при проектировании хранилища данных
- процесса ETL
- насколько реально она должна иметь ВСТАВКУ процесса ETL или UPDATE несколько миллионов записей каждый день
- будет предложение моего друга значительно помочь
Если вам нужна дополнительная информация, просто сообщите мне, и я отправлю ее.
UPDATE - дополнительная информация:
mysql> describe dimUser;
Field Type Null Key Default Extra
user_key int(10) unsigned NO PRI NULL auto_increment
id_A int(10) unsigned NO NULL
id_B int(10) unsigned NO NULL
field_4 tinyint(4) unsigned NO 0
field_5 varchar(50) YES NULL
city varchar(50) YES NULL
state varchar(2) YES NULL
country varchar(50) YES NULL
zip_code varchar(10) NO 99999
field_10 tinyint(1) NO 0
field_11 tinyint(1) NO 0
field_12 tinyint(1) NO 0
field_13 tinyint(1) NO 1
field_14 tinyint(1) NO 0
field_15 tinyint(1) NO 0
field_16 tinyint(1) NO 0
field_17 tinyint(1) NO 1
field_18 tinyint(1) NO 0
field_19 tinyint(1) NO 0
field_20 tinyint(1) NO 0
create_date datetime NO 2012-01-01 00:00:00
last_update datetime NO 2012-01-01 00:00:00
run_id int(10) unsigned NO 999
Я использовал суррогатный ключ, потому что я прочитал, что это была хорошая практика. Поскольку с точки зрения бизнеса я хочу знать о потенциальной мошеннической деятельности (скажем, в течение 200 дней пользователь связан с состоянием X, а затем на следующий день они связаны с состоянием Y - они могли бы переместиться или их учетная запись могла быть скомпрометировано), поэтому географические данные сохраняются. Поле id_B может иметь несколько различных значений id_A, связанных с ним, но мне интересно знать разные (id_A, id_B) кортежи. В контексте этой информации мой друг предположил, что первичным ключом является что-то вроде (id_A, id_B, zip_code).
Для большинства ежедневных процессов ETL (> 80%) я ожидаю, что для существующих записей будут обновлены следующие поля: field_10 - field_14, last_update и run_id (это поле является внешним ключом в моей таблице etlLog и используется для целей аудита ETL).
Если вы измените свой первичный ключ на то, что может измениться во время обновления, тогда индекс нужно будет пересчитывать каждый раз, когда он обновляется, что будет медленнее. Кажется очень странным, что потребуется 4 минуты, чтобы обновить только 100 строк на средней таблице, возможно, проблема с вашим скриптом, а не с схемой. Вы пробовали тестировать обновления непосредственно в sql vs из вашего скрипта? – limscoder
как вы придумали несколько миллионов каждый день? –
Ваш ключ в порядке, вы используете ключевой конвейер при загрузке? Что вы делаете на димджере? –