Na consulta abaixo, from
e tid
são índices da replies
tabela.
SELECT * FROM `replies`
WHERE `from`="<userId>"
OR `tid` IN (SELECT `tid` FROM `posts` WHERE `from`="<userId>")
Ao usar "OR", parece que ele faz uma varredura completa da tabela (~ 3 milhões de linhas). O EXPLAIN
diz que uma possível chave seria from
, mas não usa nenhuma.
No entanto, na consulta abaixo, frid_lt
e frid_gt
são indexados. As duas colunas estão em um índice complexo (frid_lt, frid_gt), mas frid_gt
também possui seu próprio índice.
SELECT `mid` FROM `messages`
WHERE `frid_lt`="<userId>" OR `frid_gt`="<userId>"
E esta consulta usa dois índices. O EXPLAIN
diz "index_merge" e "Usando sort_union(frid_lt,frid_gt); Usando where".
Por que a primeira consulta não usa uma mesclagem de índice?
Existe alguma melhoria que eu possa fazer para que o mecanismo também use uma mesclagem de índice?
OR
não otimiza bem. Uma solução comum é usarUNION
:Observe que também evitei o geralmente ineficiente
IN ( SELECT ... )
Para maior desempenho, tenha estes índices:
(E observe que
PRIMARY KEY
é um índice, então não adicione um índice redundante.)Em seu segundo exemplo, a "mesclagem de índice" que você experimentou pode ou não ser mais rápida que um arquivo
UNION
.Ah, é uma ATUALIZAÇÃO
Para otimizar
UPDATE
, faça dois separadosUPDATEs
(noUNION
, noOR
). Um verifica diretamentefrom
. O outro é um "UPDATE multi-table" (veja o manual) similar ao segundo select acima.