Consultas de diagnóstico para ajuste da consulta - Amazon Redshift

Consultas de diagnóstico para ajuste da consulta

Use as consultas a seguir para identificar problemas com consultas ou tabelas subjacentes que possam afetar a performance da consulta. Recomendamos o uso dessas consultas com os processos de ajuste de consulta abordados em Analisar e melhorar as consultas.

Identificar consultas que são os principais candidatos para ajuste

A consulta a seguir identifica as 50 instruções com maior consumo de tempo que tenham sido executadas nos últimos 7 dias. Você pode usar os resultados para identificar consultas que estão demandando um tempo além do normal. Você também pode identificar consultas executadas com frequência (as que aparecem mais de uma vez no conjunto de resultados). Essas consultas frequentemente são boas candidatas para ajustar o aprimoramento da performance do sistema.

Essa consulta também fornece uma contagem dos eventos de alerta associados a cada consulta identificada. Esses alertas fornecem detalhes que você pode usar para melhorar a performance da consulta. Para ter mais informações, consulte Revisar alertas da consulta.

select trim(database) as db, count(query) as n_qry, max(substring (qrytext,1,80)) as qrytext, min(run_minutes) as "min" , max(run_minutes) as "max", avg(run_minutes) as "avg", sum(run_minutes) as total, max(query) as max_query_id, max(starttime)::date as last_run, sum(alerts) as alerts, aborted from (select userid, label, stl_query.query, trim(database) as database, trim(querytxt) as qrytext, md5(trim(querytxt)) as qry_md5, starttime, endtime, (datediff(seconds, starttime,endtime)::numeric(12,2))/60 as run_minutes, alrt.num_events as alerts, aborted from stl_query left outer join (select query, 1 as num_events from stl_alert_event_log group by query ) as alrt on alrt.query = stl_query.query where userid <> 1 and starttime >= dateadd(day, -7, current_date)) group by database, label, qry_md5, aborted order by total desc limit 50;

Identificar tabelas com desvio de dados ou linhas não classificadas

A seguinte consulta identifica as tabelas que possuem uma distribuição desigual de dados (desvio de dados) ou uma porcentagem alta de linhas não classificadas.

Um valor skew baixo indica que os dados daquela tabela estão distribuídos adequadamente. Se uma tabela tem um valor skew de 4,00 ou mais, considere modificar seu estilo de distribuição de dados. Para ter mais informações, consulte Distribuição de dados pouco satisfatória.

Se uma tabela tem um valor pct_unsorted maior que 20 por cento, considere executar o comando VACUUM. Para ter mais informações, consulte Linhas não classificadas ou mal classificadas.

Você também deve revisar os valores mbytes e pct_of_total de cada tabela. Essas colunas identificam o tamanho da tabela e a porcentagem de espaço bruto em disco que a tabela utiliza. O espaço em disco bruto inclui o espaço reservado pelo Amazon Redshift para uso interno, portanto, é maior do que a capacidade nominal do disco, que é a quantidade de espaço em disco disponível para o usuário. Use essas informações para verificar se você tem espaço livre em disco igual a pelo menos 2,5 vezes o tamanho de sua maior tabela. Ter esse espaço disponível permite que o sistema grave resultados intermediários no disco ao processar consultas complexas.

select trim(pgn.nspname) as schema, trim(a.name) as table, id as tableid, decode(pgc.reldiststyle,0, 'even',1,det.distkey ,8,'all') as distkey, dist_ratio.ratio::decimal(10,4) as skew, det.head_sort as "sortkey", det.n_sortkeys as "#sks", b.mbytes, decode(b.mbytes,0,0,((b.mbytes/part.total::decimal)*100)::decimal(5,2)) as pct_of_total, decode(det.max_enc,0,'n','y') as enc, a.rows, decode( det.n_sortkeys, 0, null, a.unsorted_rows ) as unsorted_rows , decode( det.n_sortkeys, 0, null, decode( a.rows,0,0, (a.unsorted_rows::decimal(32)/a.rows)*100) )::decimal(5,2) as pct_unsorted from (select db_id, id, name, sum(rows) as rows, sum(rows)-sum(sorted_rows) as unsorted_rows from stv_tbl_perm a group by db_id, id, name) as a join pg_class as pgc on pgc.oid = a.id join pg_namespace as pgn on pgn.oid = pgc.relnamespace left outer join (select tbl, count(*) as mbytes from stv_blocklist group by tbl) b on a.id=b.tbl inner join (select attrelid, min(case attisdistkey when 't' then attname else null end) as "distkey", min(case attsortkeyord when 1 then attname else null end ) as head_sort , max(attsortkeyord) as n_sortkeys, max(attencodingtype) as max_enc from pg_attribute group by 1) as det on det.attrelid = a.id inner join ( select tbl, max(mbytes)::decimal(32)/min(mbytes) as ratio from (select tbl, trim(name) as name, slice, count(*) as mbytes from svv_diskusage group by tbl, name, slice ) group by tbl, name ) as dist_ratio on a.id = dist_ratio.tbl join ( select sum(capacity) as total from stv_partitions where part_begin=0 ) as part on 1=1 where mbytes is not null order by mbytes desc;

Como identificar consultas com loops aninhados

A seguinte consulta identifica consultas que tiveram eventos de alerta registrados para loops aninhados. Para obter informações sobre como corrigir a condição de loop aninhado, consulte Loop aninhado.

select query, trim(querytxt) as SQL, starttime from stl_query where query in ( select distinct query from stl_alert_event_log where event like 'Nested Loop Join in the query plan%') order by starttime desc;

Como revisar os tempos de espera na fila para consultas

A consulta a seguir mostra quanto tempo as consultas recentes esperaram por uma vaga disponível em uma fila de consulta antes da execução. Se você vir uma tendência de altos tempos de espera, poderá modificar sua configuração de fila de consulta para melhor rendimento. Para ter mais informações, consulte Implementar o WLM manual.

select trim(database) as DB , w.query, substring(q.querytxt, 1, 100) as querytxt, w.queue_start_time, w.service_class as class, w.slot_count as slots, w.total_queue_time/1000000 as queue_seconds, w.total_exec_time/1000000 exec_seconds, (w.total_queue_time+w.total_Exec_time)/1000000 as total_seconds from stl_wlm_query w left join stl_query q on q.query = w.query and q.userid = w.userid where w.queue_start_Time >= dateadd(day, -7, current_Date) and w.total_queue_Time > 0 and w.userid >1 and q.starttime >= dateadd(day, -7, current_Date) order by w.total_queue_time desc, w.queue_start_time desc limit 35;

Como revisar alertas de consulta por tabela

A consulta a seguir identifica as tabelas que tiveram eventos de alerta registrados e também identifica que tipo de alerta surge com mais frequência.

Se o valor minutes para uma linha com uma tabela identificada for alto, verifique a tabela para ver se ela precisa de manutenção de rotina, tal como a execução de ANALYZE ou VACUUM nela.

Se o valor count for alto para uma linha mas o valor table for nulo, execute uma consulta em STL_ALERT_EVENT_LOG pelo valor event associado para investigar por que esse alerta está sendo ativado com mais frequência.

select trim(s.perm_table_name) as table, (sum(abs(datediff(seconds, s.starttime, s.endtime)))/60)::numeric(24,0) as minutes, trim(split_part(l.event,':',1)) as event, trim(l.solution) as solution, max(l.query) as sample_query, count(*) from stl_alert_event_log as l left join stl_scan as s on s.query = l.query and s.slice = l.slice and s.segment = l.segment and s.step = l.step where l.event_time >= dateadd(day, -7, current_Date) group by 1,3,4 order by 2 desc,6 desc;

Como identificar tabelas com estatísticas ausentes

A consulta a seguir fornece uma contagem das consultas que você está executando em tabelas cujas estatísticas estão ausentes. Se essa consulta retornar qualquer linha, verifique o valor plannode para determinar a tabela afetada e, então, execute ANALYZE nela.

select substring(trim(plannode),1,100) as plannode, count(*) from stl_explain where plannode like '%missing statistics%' group by plannode order by 2 desc;