O blogue da AWS

As 10 melhores técnicas de ajuste de desempenho para o Amazon Redshift

Ian Meyers é um gerente sênior de arquitetura de soluções da AWS
Thiago Paulino é um arquitetura de soluções da AWS
Zach Christopherson, um engenheiro de banco de dados do Amazon Redshift, colaborou nesta postagem

 

O Amazon Redshift é um data warehouse para processamento de dados em paralelo, totalmente gerenciado, em escala de petabytes que oferece operações simples e de alto desempenho. Os clientes usam o Amazon Redshift para diversas finalidades, desde a aceleração de ambientes de bancos de dados existentes que possuem dificuldade de escalabilidade, até a ingestão de logs de aplicações web para casos de uso de análise de big data. O Amazon Redshift fornece uma interface de driver JDBC/ODBC padrão de mercado, que permite que os clientes se conectem às suas ferramentas de business intelligence existentes e reutilizem consultas de análises existentes.

O Amazon Redshift pode executar qualquer tipo de modelo dados, desde um modelo de terceira forma normal do sistema de transações de produção, até star e snowflake schemas ou tabelas simples. Ao adotar o Amazon Redshift, os clientes devem considerar sua arquitetura para garantir que seu modelo de dados seja implantado e mantido corretamente pelo banco de dados. Esta postagem descreve os problemas mais comuns que os clientes encontram ao adotar o Amazon Redshift e fornece orientações concretas de como resolver cada um deles. Se você resolver cada um desses itens, você deverá obter o desempenho ideal de consultas, e escalar efetivamente para atender à demanda dos clientes.

 

Problema nº 1: codificação incorreta de coluna

O Amazon Redshift é um banco de dados orientado a colunas, o que significa que, em vez de organizar os dados por linhas, os dados são armazenados por colunas, e as linhas são extraídas do armazenamento de colunas em tempo de execução. Essa arquitetura é particularmente adequada para consultas de análise em tabelas com um grande número de colunas, onde a maioria das consultas acessam apenas um subconjunto de todas as dimensões e medidas possíveis. O Amazon Redshift é capaz de acessar apenas esses blocos no disco que são para colunas incluídas na consulta SELECT ou WHERE, e não precisa ler todos os dados da tabela para avaliar uma consulta. Os dados armazenados por coluna também devem ser codificados (consulte Escolher um tipo de compactação de colunas no Guia do desenvolvedor de banco de dados do Amazon Redshift), o que significa que eles são altamente compactados para oferecer desempenho de leitura elevado. Isso também significa que o Amazon Redshift não exige a criação e a manutenção de índices: cada coluna é praticamente seu próprio índice, com apenas a estrutura certa para os dados que estão sendo armazenados.

A execução de um cluster do Amazon Redshift sem codificação de colunas não é considerada uma boa prática, e os clientes percebem grandes ganhos de desempenho quando garantem que a codificação de colunas é aplicada de forma ideal. Para determinar se você está adotando a prática recomendada, você pode usar a visualização v_extended_table_info no repositório GitHub de Utilitários do Amazon Redshift. Crie a visualização e, em seguida, execute a consulta a seguir para determinar se alguma tabela tem colunas sem a aplicação de codificação:

SELECT database, tablename, columns 
FROM admin.v_extended_table_info 
ORDER BY database;

Depois disso, analise as tabelas e colunas que não estão codificadas executando a consulta a seguir:

SELECT trim(n.nspname || '.' || c.relname) AS "table",
  trim(a.attname) AS "column",
  format_type(a.atttypid, a.atttypmod) AS "type",
  format_encoding(a.attencodingtype::integer) AS "encoding",
  a.attsortkeyord AS "sortkey"
FROM pg_namespace n, pg_class c, pg_attribute a
WHERE n.oid = c.relnamespace
AND c.oid = a.attrelid
AND a.attnum > 0
AND NOT a.attisdropped and n.nspname NOT IN ('information_schema','pg_catalog','pg_toast')
AND format_encoding(a.attencodingtype::integer) = 'none'
AND c.relkind='r'
AND a.attsortkeyord != 1
ORDER BY n.nspname, c.relname, a.attnum;

Se descobrir que você tem tabelas sem a codificação ideal de colunas, use o Utilitário de codificação de colunas do Amazon Redshift no repositório Utilitários para aplicar a codificação. Esse utilitário de linha de comando usa o comando ANALYZE COMPRESSION em cada tabela. Se a codificação for necessária, ele gerará um script SQL que cria uma nova tabela com a codificação correta, copia todos os dados na nova tabela e, em seguida, renomeia de forma transacional a nova tabela para o nome antigo e retém os dados originais. (Observe que a primeira coluna em uma chave de classificação composta não deve ser codificada, e ela não é codificada por esse utilitário.)

 

Problema nº 2 – dados distorcidos na tabela

O Amazon Redshift é uma arquitetura de banco de dados distribuída, sem compartilhamento, onde cada nó no cluster armazena um subconjunto de dados. Cada nó é adicionalmente subdividido em slices, com cada slice tendo um ou mais núcleos dedicados. O número de slices por nó depende do tipo de nó do cluster. Por exemplo, cada nó de computação DS2.XL possui dois slices e cada nó de computação DS2.8XL possui 16 slices. Quando uma tabela é criada, você decide se deseja espalhar os dados igualmente entre os slices (padrão) ou atribuir os dados a slices específicos com base em uma das colunas. Com a escolha de colunas para distribuição que são comumente unidas, você pode minimizar a quantidade de dados transferidos pela rede durante a join. Isso pode aumentar significativamente o desempenho nesses tipos de consultas.

A seleção de uma boa chave de distribuição é o tópico de muitos artigos da AWS, incluindo Escolher o melhor estilo de distribuição. Veja um guia definitivo para distribuição e classificação de esquemas estrela na postagem Otimizar para esquemas estrela e classificação intercalada no Amazon Redshift. Em geral, uma boa chave de distribuição deve demonstrar as seguintes propriedades:

  • Alta cardinalidade – deve haver um grande número de valores de dados exclusivos na coluna em relação ao número de slices no cluster.
  • Distribuição uniforme/distorção baixa – idealmente, cada valor único na coluna da chave de distribuição deve ocorrer na tabela em torno do mesmo número de vezes. Isso permite que o Amazon Redshift coloque o mesmo número de registros em cada slice no cluster.
  • Comumente unida – a coluna em uma chave de distribuição deve ser uma que você normalmente une com outras tabelas. Se você tiver muitas colunas que se adequem a esse critério, você poderá escolher a coluna que é unida ao maior número de linhas em tempo de execução (normalmente, mas não sempre, essa é a coluna que é unida à maior tabela).

Uma chave de distribuição distorcida resulta em slices que não funcionam de forma igualmente firme como as outras durante a execução de consultas, exigindo CPU ou memória desbalanceada e, basicamente, executando tão rápido quanto a slice mais lenta:

Se a distorção for um problema, você geralmente verá que o desempenho do nó é irregular no cluster. Use um dos scripts de administrador no repositório GitHub de Utilitários do Amazon Redshift, como table_inspector.sql, para ver como os blocos de dados em uma chave de distribuição são mapeados para slices e nós no cluster.

Se você descobrir que existem tabelas com chaves de distribuição distorcidas, considere alterar a chave de distribuição para uma coluna que exiba alta cardinalidade e distribuição uniforme. Avalie a coluna candidata como uma chave de distribuição criando uma nova tabela usando CTAS:

CREATE TABLE my_test_table DISTKEY (<column name>) AS SELECT <column name> FROM <table name>;

Execute o script table_inspector.sql na tabela novamente para analisar a distorção dos dados.

Se não houver uma boa chave de distribuição em nenhum de seus registros, você pode descobrir que mover para a distribuição EVEN pode funcionar melhor. Para tabelas pequenas (por exemplo, tabelas de dimensão com dois milhões de linhas), você também pode usar DISTSTYLE ALL para colocar os dados da tabela na primeira slice de cada nó no cluster.

 

Problema nº 3 – consultas que não se beneficiam de chaves de classificação

As tabelas do Amazon Redshift podem ter uma coluna de chave de distribuição identificada que atua como um índice em outros bancos de dados, mas que não incorre em um custo de armazenamento como em outras plataformas (para obter mais informações, consulte Escolher chaves de classificação). Uma chave de classificação deve ser criada em colunas que são usadas mais comumente em cláusulas WHERE. Se você tiver um padrão de consultas conhecido, as chaves de classificação COMPOUND fornecerão o melhor desempenho. Se os usuários finais consultarem colunas diferentes de forma igual, use uma chave de classificação INTERLEAVED. Ao usar chaves de classificação compostas, analise suas consultas para garantir que suas cláusulas WHERE especificam as colunas de classificação na mesma ordem em que foram definidas na chave composta.

Para determinar as tabelas que não têm chaves de classificação, execute a consulta a seguir na visualização v_extended_table_info no repositório de Utilitários do Amazon Redshift:

SELECT * FROM admin.v_extended_table_info WHERE sortkey IS null;

Você pode executar um tutorial que descreve como resolver tabelas não classificadas no Guia do desenvolvedor do Amazon Redshift. Você também pode executar a consulta a seguir para gerar uma lista de chaves de classificação recomendadas com base na atividade de consultas:

SELECT ti.schemaname||'.'||ti.tablename AS "table", 
  ti.tbl_rows, 
  avg(r.s_rows_pre_filter) avg_s_rows_pre_filter, 
  round(1::float - avg(r.s_rows_pre_filter)::float/ti.tbl_rows::float,6) avg_prune_pct, 
  avg(r.s_rows) avg_s_rows, 
  round(1::float - avg(r.s_rows)::float/avg(r.s_rows_pre_filter)::float,6) avg_filter_pct, 
  ti.diststyle, 
  ti.sortkey_num, 
  ti.sortkey1, 
  trim(a.typname) "type", 
  count(distinct i.query) * avg(r.time) AS total_scan_secs, 
  avg(r.time) AS scan_time, 
  count(distinct i.query) AS num, 
  max(i.query) AS query, 
  trim(info) AS filter 
FROM stl_explain p 
JOIN stl_plan_info i 
ON (i.userid=p.userid AND i.query=p.query AND i.nodeid=p.nodeid ) 
JOIN stl_scan s 
ON (s.userid=i.userid AND s.query=i.query AND s.segment=i.segment AND s.step=i.step) 
JOIN (
  SELECT table_id,
    "table" tablename,
    schema schemaname,
    tbl_rows,
    unsorted,
    sortkey1,
    sortkey_num,
    diststyle 
  FROM svv_table_info) ti 
ON ti.table_id=s.tbl 
JOIN ( 
  SELECT query, 
    segment, 
    step, 
    datediff(s,min(starttime),max(endtime)) AS time, 
    sum(rows) s_rows, 
    sum(rows_pre_filter) s_rows_pre_filter, 
    round(sum(rows)::float/sum(rows_pre_filter)::float,6) filter_pct 
  FROM stl_scan 
  WHERE userid>1 AND starttime::date = current_date-1 AND starttime < endtime 
  GROUP BY 1,2,3 HAVING sum(rows_pre_filter) > 0 ) r 
ON (r.query = i.query AND r.segment = i.segment AND r.step = i.step) 
LEFT JOIN (
  SELECT attrelid,
    t.typname 
  FROM pg_attribute a 
  JOIN pg_type t 
  ON t.oid=a.atttypid 
  WHERE attsortkeyord IN (1,-1)) a 
ON a.attrelid=s.tbl 
WHERE s.type = 2 AND ti.tbl_rows > 1000000 AND p.info LIKE 'Filter:%' AND p.nodeid > 0 
GROUP BY 1,2,7,8,9,10,15 
ORDER BY 1, 13 desc, 11 desc;

Lembre-se de que as consultas avaliadas em uma coluna de chave de classificação não aplicam uma função do SQL à chave de classificação. Em vez disso, aplique as funções aos valores comparados para que a chave de classificação seja usada. Geralmente, isso é encontrado em colunas TIMESTAMP que são usadas em chaves de classificação.

 

Problema nº 4 – Tabelas sem estatísticas ou que precisam de aplicação de vacuum

O Amazon Redshift, como outros bancos de dados, exige estatísticas sobre tabelas e a composição de blocos de dados que estão sendo armazenados para tomar boas decisões ao planejar uma consulta (para obter mais informações, consulte Analisar tabelas). Sem uma boa estatística, o otimizador pode fazer escolhas não ideais sobre a ordem na qual acessar tabelas ou sobre como unir conjuntos de dados.

O tópico Histórico do comando ANALYZE no Guia do desenvolvedor do Amazon Redshift fornece consultas que ajudam a resolver estatísticas ausentes ou obsoletas, e você também pode simplesmente executar o script de administrador missing_table_stats.sql para determinar quais tabelas não têm estatísticas, ou executar a instrução a seguir para determinar quais tabelas têm estatísticas obsoletas:

SELECT database, schema || '.' || "table" AS "table", stats_off 
FROM svv_table_info 
WHERE stats_off > 5 
ORDER BY 2;

No Amazon Redshift, os blocos de dados são imutáveis. Quando linhas são EXCLUÍDAS ou ATUALIZADAS, elas são simplesmente excluídas logicamente (sinalizadas para exclusão) mas não são removidas fisicamente do disco. As atualizações resultam na gravação de um novo bloco com novos dados acrescentados. Essas duas operações fazem com que a versão anterior da linha continue a consumir espaço em disco e continue a ser varrida quando uma consulta varre a tabela. Como resultado, o espaço de armazenamento da tabela é aumentado e o desempenho é degradado devido à I/O que, de outra forma, pode ser evitada durante as varreduras. Um comando VACUUM recupera o espaço de linhas excluídas e restaura a ordem de classificação.

Você pode usar o script de administrador perf_alert.sql para identificar tabelas que tiveram alertas sobre a varredura de um grande número de linhas excluídas acionados nos últimos sete dias.

Para resolver problemas com tabelas com estatísticas ausentes ou obsoletas ou quando aplicar vacuum é necessário, execute outro utilitário dos Laboratórios da AWS, Esquema de análise e aplicação de vacuum. Isso garante que você mantenha as estatísticas sempre atualizadas, e aplique vacuum apenas em tabelas que realmente precisam de reorganização.

 

Problema nº 5 – Tabelas com colunas VARCHAR muito grandes

Durante o processamento de consultas complexas, os resultados de consultas intermediárias podem precisar ser armazenados em blocos temporários. Essas tabelas temporárias não são compactadas, portanto, colunas desnecessariamente grandes consomem memória e espaço temporário em disco excessivos, o que pode afetar o desempenho das consultas. Para obter mais informações, consulte Usar o menor tamanho de coluna possível.

Use a consulta a seguir para gerar uma lista de tabelas que devem ter suas larguras máximas de coluna analisadas:

SELECT database, schema || '.' || "table" AS "table", max_varchar 
FROM svv_table_info 
WHERE max_varchar > 150 
ORDER BY 2;

Depois que você tiver uma lista das tabelas, identifique as colunas das tabelas que têm colunas varchar grandes e determine a largura máxima verdadeira para cada coluna grande usando a consulta a seguir:

SELECT max(len(rtrim(column_name))) 
FROM table_name;

Em alguns casos, você pode ter colunas do tipo VARCHAR grandes porque está armazenando fragmentos de JSON na tabela que você consulta com funções de JSON. Se você consultar as consultas principais em execução no banco de dados usando o script de administrador top_queries.sql, preste atenção especial às consultas SELECT * que incluem a coluna de fragmentos de JSON. Se os usuários finais consultarem essas colunas grandes, mas não usarem realmente as funções de execução do JSON nelas, considere movê-las para outra tabela que contenha apenas a coluna de chave primária da tabela original e a coluna de JSON.

Se descobrir que a tabela tem colunas que são maiores que o necessário, você precisará criar uma versão da tabela novamente com as larguras de colunas apropriadas executando uma cópia em profundidade.

 

Problema nº 6 – consultas em espera em slots de filas

O Amazon Redshift executa consultas usando um sistema de filas conhecido como gerenciamento de carga de trabalho (WLM). Você pode definir até oito filas para cargas de trabalho separadas umas das outras, e definir a simultaneidade em cada fila para atender aos requisitos gerais de throughput.

Em alguns casos, a fila à qual um usuário ou consulta foi atribuído está completamente ocupada e a consulta do usuário precisa aguardar que um slot seja aberto. Durante esse tempo, o sistema não está executando a consulta, o que é um sinal de que você pode precisar aumentar a simultaneidade.

Primeiro, você precisa determinar se as consultas estão sendo enfileiradas usando o script de administrador queuing_queries.sql. Analise a simultaneidade máxima de que seu cluster precisou no passado com wlm_apex.sql, até uma análise histórica de hora em hora com wlm_apex_hourly.sql. Lembre-se de que, embora o aumento da simultaneidade permita que mais consultas sejam executadas, cada consulta obterá um compartilhamento menor da memória alocada à sua fila (a menos que você a aumente). Você pode descobrir que com o aumento da simultaneidade, algumas consultas precisarão usar armazenamento em disco temporário para concluir, o que também não é ideal (consulte a seguir).

 

Problema nº 7 – Consultas baseadas em disco

Se uma consulta não puder ser executada completamente na memória, ela poderá precisar usar armazenamento temporário baseado em disco para partes de um plano de explicação. O I/O adicional no disco diminui a velocidade da consulta. Isso pode ser resolvido aumentando a quantidade de memória alocada para uma sessão (para obter mais informações, consulte Alocação de memória dinâmica do WLM).

Para determinar se algumas consultas foram gravadas em disco, use a consulta a seguir:

SELECT q.query, trim(q.cat_text)
FROM (
  SELECT query, 
    replace( listagg(text,' ') WITHIN GROUP (ORDER BY sequence), '\\n', ' ') AS cat_text 
    FROM stl_querytext 
    WHERE userid>1 
    GROUP BY query) q
JOIN (
  SELECT distinct query 
  FROM svl_query_summary 
  WHERE is_diskbased='t' 
  AND (LABEL LIKE 'hash%' OR LABEL LIKE 'sort%' OR LABEL LIKE 'aggr%') 
  AND userid > 1) qs 
ON qs.query = q.query;

Com base no usuário ou nas regras de atribuição de filas, você pode aumentar a quantidade de memória fornecida à fila selecionada para evitar que as consultas precisem ser despejadas em disco para serem concluídas. Você também pode aumentar o WLM_QUERY_SLOT_COUNT da sessão, do padrão de 1 para a simultaneidade máxima da fila. Conforme descrito no Problema nº 6, isso pode resultar em consultas enfileiradas, portanto, use com cautela.

 

Problema nº 8 – Esperas de filas de confirmação

O Amazon Redshift foi desenvolvido para consultas de análise e não para processamento de transações. O custo de COMMIT é relativamente alto, e o uso excessivo de COMMIT pode resultar em consultas em espera para acesso a uma fila de commit.

Se estiver realizando commit com muita frequência em seu banco de dados, você começará a ver um aumento de esperas na fila de commit, o que pode ser visto com o script de administrador commit_stats.sql. Esse script mostra o maior comprimento de fila e o tempo de fila para consultas executadas nos últimos dois dias. Se você tiver consultas em espera na fila de confirmação, procure as sessões que estão confirmando várias vezes por sessão, como trabalhos de ETL que estão registrando o progresso em logs ou cargas de dados ineficientes.

 

Problema nº 9 – Cargas de dados ineficientes

As práticas recomendadas do Amazon Redshift sugerem o uso do comando COPY para executar cargas de dados. Essa operação da API usa todos os nós de computação no cluster para carregar dados em paralelo, de origens como o Amazon S3, o Amazon DynamoDB, sistemas de arquivos Amazon EMR HDFS ou qualquer conexão SSH.

Ao executar cargas de dados, você deve compactar os arquivos a serem carregados sempre que possível. O Amazon Redshift oferece suporte à compactação GZIP e LZO. É mais eficiente carregar um grande número de arquivos pequenos que um grande, e a contagem ideal de arquivos é um múltiplo da contagem de slices. O número de slices por nó depende do tamanho do nó do cluster. Garantindo que você tenha um número igual de arquivos por slice, você saberá que a execução do COPY usará os recursos do cluster uniformemente e concluirá o mais rápido possível.

A consulta a seguir calcula as estatísticas de cada carga:

SELECT a.tbl,
  trim(c.nspname) AS "schema", 
  trim(b.relname) AS "tablename", 
  sum(a.rows_inserted) AS "rows_inserted", 
  sum(d.distinct_files) AS files_scanned,  
  sum(d.MB_scanned) AS MB_scanned, 
  (sum(d.distinct_files)::numeric(19,3)/count(distinct a.query)::numeric(19,3))::numeric(19,3) AS avg_files_per_copy, 
  (sum(d.MB_scanned)/sum(d.distinct_files)::numeric(19,3))::numeric(19,3) AS avg_file_size_mb, 
  count(distinct a.query) no_of_copy, 
  max(a.query) AS sample_query, 
  (sum(d.MB_scanned)*1024*1000000/SUM(d.load_micro)) AS scan_rate_kbps, 
  (sum(a.rows_inserted)*1000000/SUM(a.insert_micro)) AS insert_rate_rows_ps 
FROM 
  (SELECT query, 
    tbl, 
    sum(rows) AS rows_inserted, 
    max(endtime) AS endtime, 
    datediff('microsecond',min(starttime),max(endtime)) AS insert_micro 
  FROM stl_insert 
  GROUP BY query, tbl) a,      
  pg_class b, 
  pg_namespace c,                 
  (SELECT b.query, 
    count(distinct b.bucket||b.key) AS distinct_files, 
    sum(b.transfer_size)/1024/1024 AS MB_scanned, 
    sum(b.transfer_time) AS load_micro 
  FROM stl_s3client b 
  WHERE b.http_method = 'GET' 
  GROUP BY b.query) d 
WHERE a.tbl = b.oid AND b.relnamespace = c.oid AND d.query = a.query 
GROUP BY 1,2,3 
ORDER BY 4 desc;

A consulta a seguir mostra o tempo levado para carregar uma tabela e o tempo levado para atualizar as estatísticas da tabela, ambas em segundos e como uma porcentagem do processo geral de carregamento:

 

SELECT a.userid, 
  a.query, 
  round(b.comp_time::float/1000::float,2) comp_sec, 
  round(a.copy_time::float/1000::float,2) load_sec, 
  round(100*b.comp_time::float/(b.comp_time + a.copy_time)::float,2) ||'%' pct_complyze, 
  substring(q.querytxt,1,50) 
FROM (
  SELECT userid, 
    query, 
    xid, 
    datediff(ms,starttime,endtime) copy_time 
  FROM stl_query q 
  WHERE (querytxt ILIKE 'copy %from%') 
  AND exists (
    SELECT 1 
    FROM stl_commit_stats cs 
    WHERE cs.xid=q.xid) 
  AND exists (
    SELECT xid 
    FROM stl_query 
    WHERE query IN (
      SELECT distinct query 
      FROM stl_load_commits))) a 
LEFT JOIN (
  SELECT xid, 
    sum(datediff(ms,starttime,endtime)) comp_time 
  FROM stl_query q 
  WHERE (querytxt LIKE 'COPY ANALYZE %' OR querytxt LIKE 'analyze compression phase %') 
  AND exists (
    SELECT 1 
    FROM stl_commit_stats cs 
    WHERE cs.xid=q.xid) 
  AND exists (
    SELECT xid 
    FROM stl_query 
    WHERE query IN (
      SELECT distinct query 
      FROM stl_load_commits)) 
  GROUP BY 1) b 
ON b.xid = a.xid 
JOIN stl_query q 
ON q.query = a.query 
WHERE (b.comp_time IS NOT null) 
ORDER BY 6,5;

Um padrão não recomendado é inserir dados diretamente no Amazon Redshift, com INSERT de registros únicos ou o uso de uma instrução INSERT de vários valores, o que permite que até 16 MB de dados sejam inseridos de uma vez. Essas são operações baseadas no nó líder, e podem criar gargalos significativos no desempenho estourando a rede do nó líder enquanto os dados são distribuídos pelo líder para os nós de computação.

 

Problema nº 10 – Uso ineficiente de tabelas temporárias

O Amazon Redshift fornece tabelas temporárias, que são como tabelas normais, mas que são visíveis apenas dentro de uma única sessão. Quando o usuário se desconecta da sessão, as tabelas são excluídas automaticamente. As tabelas temporárias podem ser criadas usando a sintaxe CREATE TEMPORARY TABLE ou emitindo uma SELECT … INTO #TEMP_TABLE query. A instrução CREATE TABLE fornece controle total sobre a definição da tabela temporária, enquanto os comandos SELECT … INTO e C(T)TAS usam os dados de entrada para determinar os nomes, os tamanhos e os tipos de dados das colunas e usam propriedades de armazenamento padrão.

Essas propriedades de armazenamento padrão podem causar problemas se não forem consideradas com cautela. A estrutura de tabela padrão do Amazon Redshift é usar distribuição EVEN sem codificação de colunas. Essa é uma estrutura de dados não é ideal para muitos tipos de consultas e, se estiver usando a sintaxe SELECT…INTO, você não poderá definir a codificação ou a distribuição de colunas e as chaves de classificação. Se você usar a sintaxe CREATE TABLE AS (CTAS), você poderá especificar um estilo de distribuição e chaves de classificação, e o Redshift aplicará automaticamente a codificação LZO a tudo que não seja chaves de classificação, booleans, reals e doubles. Se você não considerar essa codificação automática como ideal e precisar de mais controle, use a sintaxe CREATE TABLE em vez de CTAS.

Se estiver criando tabelas temporárias, recomendamos converter toda sintaxe SELECT…INTO para usar a instrução CREATE. Isso garante que suas tabelas temporárias tenham codificações de coluna e sejam distribuídas de uma maneira compreensiva para as outras entidades que fazem parte do fluxo de trabalho. Para realizar uma conversão de uma instrução que usa:

SELECT column_a, column_b INTO #my_temp_table FROM my_table;

Você deve analisar a tabela temporária para obter a codificação ideal da coluna:

E, em seguida, converter a instrução select/into em:

 

BEGIN;
CREATE TEMPORARY TABLE my_temp_table(
column_a varchar(128) encode lzo,
column_b char(4) encode bytedict)
distkey (column_a) -- Assuming you intend to join this table on column_a
sortkey (column_b); -- Assuming you are sorting or grouping by column_b
 
INSERT INTO my_temp_table SELECT column_a, column_b FROM my_table;
COMMIT;

Você também pode analisar as estatísticas na tabela temporária, se ela for usada como um JOIN TABLE para consultas subsequentes:

ANALYZE my_temp_table;

Dessa maneira, você retém a funcionalidade de usar tabelas temporárias, mas controla a colocação dos dados no cluster por meio da atribuição da chave de distribuição, e tira proveito da natureza colunar do Amazon Redshift com o uso de codificação de colunas.

Dica: Usar alertas do plano de explicação

A última dica é usar informações de diagnóstico do cluster durante a execução da consulta. Isso é armazenado em uma visualização extremamente útil chamada STL_ALERT_EVENT_LOG. Use o script de administrador perf_alert.sql para diagnosticar problemas encontrados pelo cluster nos últimos sete dias. Esse é um recurso inestimável para compreender como o cluster se desenvolve com o tempo.

 

Resumo

O Amazon Redshift é um data warehouse poderoso e totalmente gerenciado que pode oferecer desempenho significativamente maior e menor custo na nuvem. Embora o Amazon Redshift possa executar qualquer tipo de modelo de dados, você pode evitar armadilhas que podem reduzir o desempenho ou aumentar o custo, estando ciente de como os dados são armazenados e gerenciados. Execute um conjunto simples de consultas de diagnóstico para obter problemas comuns e garanta que você obtenha o melhor desempenho possível.

Se tiver perguntas ou sugestões, deixe um comentário :)