Tenho um banco de dados MariaDB 10.5.10, com uma tabela activity
composta por 150.000 linhas. ele contém:
- um
id
campo (inteiro, chave primária) - a
tenant
. Existem cerca de 85.000 linhas com inquilino = 12 - an
activity_type
(inteiro, atuando como uma chave para outra tabelaactivity_type
)
Outra tabela, activity_type
, tem 6 linhas, com um id
(chave primária, inteiro)
Essa consulta, que é gerada a partir de um ORB (e que praticamente não posso modificar) requer cerca de 4 a 5 segundos para ser executada e gostaria de fazê-la funcionar mais rápido:
select count(activity.id) from activity
left join activity_type on activity.type = activity_type.id
where tenant = 12 ;
Quando removo a left join
linha, ela roda muito mais rápido, cerca de 0,7 segundos.
Usando explain
, posso ver que sem left join
, a extra
coluna menciona using index
(na verdade, o índice da tenant
coluna):
explain select SQL_NO_CACHE count(activity.id) from activity
where tenant = 12;
Mas com left join
a extra
coluna está vazia:
explain select SQL_NO_CACHE count(activity.id) from activity
left join activity_type on activity.type = activity_type.id
where tenant = 12;
E com a cláusula left join
but NO where
, também mostra Using index
:
explain select SQL_NO_CACHE count(activity.id) from activity
left join activity_type on activity.type = activity_type.id;
Você poderia me ajudar a melhorar o desempenho quando as instruções LEFT JOIN
e as WHERE
estão presentes?
Observe que:
- o
LEFT JOIN
não adiciona nenhuma linha aos resultados, porque há apenas umaactivity_type
linha por atividade (também tentei adicionar umUNIQUE
índice noactivity_type.id
, mas não muda nada no desempenho) - porém preciso da
LEFT JOIN
declaração, pois em alguns casos, os usuários podem querer adicionar mais critérios (nawhere
cláusula) relacionados aos campos daactivity_type
tabela.
Muito obrigado!
Adicione o seguinte índice à
activity
tabelaConsulte índices compostos (compostos)
Não, você não. Construa a consulta desejada com base nos critérios que o usuário fornecer a você. Parece que
AND activity_type = '...'
é o único caso em que aLEFT JOIN
cláusula é necessária.Outras dicas:
COUNT(*)
em vez deCOUNT(x)
a menos que você precise verificarx IS NOT NULL
.SHOW CREATE TABLE
para que possamos saber exatamente quais índices, tipos de dados, etc, estão nas tabelas.LEFT JOIN
que não seja realmente necessário.Os EXPLICA:
(tenent, id)
type
.PRIMARY KEY(id)
'agrupado' como um "índice" para os dados. Portanto, "Usar índice" neste caso significa "varredura de tabela".Confuso? Eu não culpo você.
Eu usaria uma string curta para "tipos" e a incluiria como uma coluna em
activity
. Isso eliminaria oJOIN
(a menos que haja algo mais de interesse na tabela 'types'). Mas então, você pode precisar deINDEX(tenant, type)
, especialmente para a versão simplificada da consulta original.