ClickHouse/docs/ru/sql-reference/statements/insert-into.md
2020-12-20 18:18:47 +03:00

8.2 KiB
Raw Blame History

toc_priority toc_title
33 INSERT INTO

INSERT

Добавление данных.

Базовый формат запроса:

INSERT INTO [db.]table [(c1, c2, c3)] VALUES (v11, v12, v13), (v21, v22, v23), ...

Вы можете указать список столбцов для вставки, используя синтаксис (c1, c2, c3) или синтаксис (COLUMNS(c1, c2, c3)). Также можно использовать выражение cо звездочкой и/или модификаторами, такими как APPLY, EXCEPT, REPLACE.

В качестве примера рассмотрим таблицу:

SHOW CREATE insert_select_testtable
┌─statement────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ CREATE TABLE insert_select_testtable
(
    `a` Int8,
    `b` String,
    `c` Int8
)
ENGINE = MergeTree()
ORDER BY a
SETTINGS index_granularity = 8192 │
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
INSERT INTO insert_select_testtable (*) VALUES (1, 'a', 1) 

Если вы хотите вставить данные во все столбцы, кроме 'b', вам нужно передать столько значений, сколько столбцов вы указали в скобках:

INSERT INTO insert_select_testtable (* EXCEPT(b)) Values (2, 2)
SELECT * FROM insert_select_testtable
┌─a─┬─b─┬─c─┐
│ 2 │   │ 2 │
└───┴───┴───┘
┌─a─┬─b─┬─c─┐
│ 1 │ a │ 1 │
└───┴───┴───┘

В этом примере мы видим, что вторая строка содержит столбцы a и c, заполненные переданными значениями и b, заполненный значением по умолчанию. Если список столбцов не включает все существующие столбцы, то все остальные столбцы заполняются следующим образом:

  • Значения, вычисляемые из DEFAULT выражений, указанных в определении таблицы.
  • Нули и пустые строки, если DEFAULT не определены.

Если strict_insert_defaults=1, то столбцы, для которых не определены DEFAULT, необходимо перечислить в запросе.

В INSERT можно передавать данные любого формата, который поддерживает ClickHouse. Для этого формат необходимо указать в запросе в явном виде:

INSERT INTO [db.]table [(c1, c2, c3)] FORMAT format_name data_set

Например, следующий формат запроса идентичен базовому варианту INSERT … VALUES:

INSERT INTO [db.]table [(c1, c2, c3)] FORMAT Values (v11, v12, v13), (v21, v22, v23), ...

ClickHouse отсекает все пробелы и один перенос строки (если он есть) перед данными. Рекомендуем при формировании запроса переносить данные на новую строку после операторов запроса (это важно, если данные начинаются с пробелов).

Пример:

INSERT INTO t FORMAT TabSeparated
11  Hello, world!
22  Qwerty

С помощью консольного клиента или HTTP интерфейса можно вставлять данные отдельно от запроса. Как это сделать, читайте в разделе «Интерфейсы».

Ограничения (constraints)

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

Вставка результатов SELECT

INSERT INTO [db.]table [(c1, c2, c3)] SELECT ...

Соответствие столбцов определяется их позицией в секции SELECT. При этом, их имена в выражении SELECT и в таблице для INSERT, могут отличаться. При необходимости выполняется приведение типов данных, эквивалентное соответствующему оператору CAST.

Все форматы данных кроме Values не позволяют использовать в качестве значений выражения, такие как now(), 1 + 2 и подобные. Формат Values позволяет ограниченно использовать выражения, но это не рекомендуется, так как в этом случае для их выполнения используется неэффективный вариант кода.

Не поддерживаются другие запросы на модификацию части данных: UPDATE, DELETE, REPLACE, MERGE, UPSERT, INSERT UPDATE. Вы можете удалять старые данные с помощью запроса ALTER TABLE ... DROP PARTITION.

Для табличной функции input() после секции SELECT должна следовать секция FORMAT.

Замечания о производительности

INSERT сортирует входящие данные по первичному ключу и разбивает их на партиции по ключу партиционирования. Если вы вставляете данные в несколько партиций одновременно, то это может значительно снизить производительность запроса INSERT. Чтобы избежать этого:

  • Добавляйте данные достаточно большими пачками. Например, по 100 000 строк.
  • Группируйте данные по ключу партиционирования самостоятельно перед загрузкой в ClickHouse.

Снижения производительности не будет, если:

  • Данные поступают в режиме реального времени.
  • Вы загружаете данные, которые как правило отсортированы по времени.

Оригинальная статья