Use a instrução INSERT para gravar linhas em uma tabela do Hologres. O sistema oferece suporte a dois métodos de gravação: inserção de valores explícitos com INSERT INTO ... VALUES e inserção de resultados de consulta com INSERT INTO ... SELECT.
Sintaxe
INSERT INTO <schema>.<table> [( <column> [, ...] )]
VALUES ( {<expression>} [, ...] ) [, ...]
| <query>
|
Parâmetro |
Descrição |
|
|
Nome do schema que contém a tabela de destino. |
|
|
Nome da tabela de destino. Ao usar o Realtime Compute for Apache Flink para gravar dados no Hologres, especifique uma tabela pai para rotear os dados automaticamente à tabela filha correspondente. No Hologres V1.3 ou superior, use também uma instrução INSERT com sintaxe Fixed Plan para gravar diretamente em uma tabela pai. Para obter detalhes, consulte Acelerar a execução de SQL com Fixed Plan. |
|
|
Nome da coluna de destino. Qualifique com um nome de subcampo ou subscrito de array conforme necessário. Se você gravar apenas em alguns campos de uma coluna composta, os campos restantes serão definidos como nulos. |
|
|
Valor ou expressão a atribuir à coluna correspondente. |
|
|
Instrução SELECT que fornece as linhas a inserir. Consulte SELECT. |
Funcionamento
O INSERT grava dados em logs de gravação antecipada (WAL) no modo Append Only e atualiza a tabela de memória em tempo real. Isso torna os dados imediatamente visíveis após cada gravação.
A tabela de memória tem capacidade fixa. Quando atinge o limite, o Hologres passa a usar uma nova tabela de memória e aciona um flush assíncrono para o armazenamento persistente. Durante o flush, o sistema grava muitos arquivos pequenos no Pangu. Em seguida, o Hologres mescla e ordena esses arquivos em segundo plano, em um processo chamado compactação.
Para maximizar o throughput de gravação, o Hologres adia a compressão e a ordenação para a fase de compactação. Como resultado, o uso de armazenamento aumenta durante as gravações ativas e diminui após a conclusão da compactação.
O formato do flush depende do modelo de armazenamento da tabela:
|
Modelo de armazenamento |
Formato de arquivo |
|
Orientado a linhas |
SST |
|
Orientado a colunas |
ORC |
|
Híbrido de linhas e colunas |
SST + ORC (uma gravação só é confirmada após o sucesso de ambos) |
Tabelas híbridas de linhas e colunas armazenam dados em ambos os formatos, o que aumenta a sobrecarga de armazenamento em comparação com tabelas orientadas a linhas ou a colunas.
Dicas de desempenho de gravação
O mecanismo de gravação descrito acima tem implicações práticas:
Adote o Fixed Plan para cargas de trabalho paralelas: A execução de várias instruções INSERT em paralelo na mesma tabela sem um Fixed Plan causa bloqueio no nível da tabela. Use um Fixed Plan para eliminar a contenção de bloqueios e melhorar o throughput. Consulte Acelerar a execução de SQL com Fixed Plan.
Previna picos temporários de armazenamento: O uso de armazenamento aumenta significativamente durante gravações ativas e se normaliza após a compactação. Esse comportamento é esperado e não indica problemas nos dados.
Gravar dados
Inserir valores explícitos
Use INSERT INTO ... VALUES para inserir uma ou mais linhas com valores literais.
INSERT INTO holo2mysqltest (cate_id, cate_name) VALUES
(3, 'comedy'),
(3, 'drama'),
(4, 'The Dinner Game');
Inserir a partir de uma consulta
Use INSERT INTO ... SELECT para copiar linhas de outra tabela ou do resultado de uma consulta.
INSERT INTO target_table
SELECT * FROM source_table;
A ordem das colunas no SELECT deve corresponder à lista de colunas no INSERT (ou à ordem das colunas da tabela, caso nenhuma lista seja especificada). Os tipos de dados devem ser compatíveis.
Exemplos
Inserir linhas em uma tabela interna
Crie uma tabela e insira uma linha com valores de vários tipos de dados.
CREATE TABLE holotest (
a int,
b bigint,
c bool,
e decimal(38,10),
f text,
g timestamp,
h timestamptz,
i jsonb,
j int[]
);
INSERT INTO holotest VALUES (
1,
9223372036854775807,
false,
123.123456789123,
'john',
'2020-01-01 01:01:01.123456',
'2004-10-19 10:23:54+08',
'{"a":2}',
ARRAY[1, 2, 3, 4]
);
-- Verify the inserted row
SELECT * FROM holotest;
Copiar linhas entre tabelas
CREATE TABLE holotest2 (
a int,
b bigint,
c bool
);
INSERT INTO holotest2 (a, b, c)
SELECT a, b, c FROM holotest;
-- Verify
SELECT * FROM holotest2;
Inserir em uma tabela particionada
Crie uma tabela pai particionada com tabelas filhas e, em seguida, insira dados em uma tabela filha específica.
BEGIN;
CREATE TABLE public.hologres_parent (
a text,
b int,
c timestamp,
d text
) PARTITION BY LIST(a);
CALL set_table_property('public.hologres_parent', 'orientation', 'column');
CREATE TABLE public.hologres_2022 PARTITION OF public.hologres_parent FOR VALUES IN ('2022');
CREATE TABLE public.hologres_2021 PARTITION OF public.hologres_parent FOR VALUES IN ('2021');
CREATE TABLE public.hologres_2020 PARTITION OF public.hologres_parent FOR VALUES IN ('2020');
COMMIT;
-- Insert into a specific child table
INSERT INTO public.hologres_2022 VALUES ('2022', 1, now(), 'a');
-- Verify
SELECT * FROM public.hologres_2022;
Observações de uso
Column order: Liste os nomes das colunas na instrução INSERT em qualquer ordem. Para
INSERT INTO ... SELECT, os tipos de dados das colunas selecionadas devem corresponder aos tipos das colunas de destino respectivas.Tabelas particionadas: Ao inserir dados em uma tabela pai, o valor da chave de partição em cada linha deve corresponder ao valor da chave de partição de uma tabela filha existente. O sistema não oferece suporte a gravações diretas em uma tabela pai, a menos que você utilize a sintaxe Fixed Plan (Hologres V1.3 ou superior).
Inserções paralelas: Executar múltiplas instruções INSERT simultaneamente na mesma tabela sem um Fixed Plan provoca bloqueios no nível da tabela. Cada instrução aguarda a liberação do bloqueio anterior, o que aumenta a latência. Use um Fixed Plan para evitar essa situação.
Uso de armazenamento: O consumo de armazenamento cresce substancialmente durante gravações ativas e reduz após a conclusão da compactação. Trata-se de um comportamento esperado — veja Funcionamento para mais detalhes.
Solução de problemas
ERROR: no partition of relation "<table_name>" found for row
Não existe nenhuma tabela filha para o valor da chave de partição na linha que você está tentando inserir. Crie primeiro a tabela filha correspondente:
CREATE TABLE <child_table_name> PARTITION OF <parent_table_name>
FOR VALUES IN (<value>);
Currently inserting into parent table is not supported
A tabela de destino é uma tabela pai. O Hologres não suporta a gravação direta de dados em uma tabela pai. Insira os dados em uma tabela filha específica.
Próximos passos
Acelerar a execução de SQL com Fixed Plan — elimine bloqueios no nível da tabela e melhore o throughput de gravação para cargas de trabalho INSERT paralelas
SELECT — sintaxe de consulta para uso com
INSERT INTO ... SELECTINSERT ON CONFLICT — utilize semântica UPSERT para inserir ou atualizar linhas com base na resolução de conflitos