Pergunta

NOTA:. A pergunta original é discutível, mas digitalização para o fundo para algo relevante

Eu tenho uma consulta que eu quero otimizar que é algo como isto:

select cols from tbl where col = "some run time value" limit 1;

Eu quero saber o que as chaves estão sendo usadas, mas o que eu passar para explicar, é capaz de otimizar a cláusula WHERE para nada ( "Impossible ONDE notado ..."), porque eu alimentava uma constante.

  • Existe uma maneira de dizer mysql não fazer otimizações constantes em explicar?
  • Am I faltando alguma coisa?
  • Existe uma maneira melhor para obter a necessidade informação que eu?

Edit: EXPLAIN parece estar dando-me o plano de consulta que irá resultar de valores constantes. Como a consulta é parte de um procedimento armazenado (e planos IIRC consulta em SPOC são gerados antes que eles são chamados), este não me faz bem porque o valor não são constantes. O que eu quero é para descobrir o que consulta planejar o otimizador irá gerar quando ele não sabe qual é o valor real será.

Am I faltando soemthing?

Edit2: Pedindo ao redor em outros lugares, parece que o MySQL sempre regenera consulta planos a menos que você sair do seu caminho para torná-lo voltar a usá-los. Mesmo em procedimentos armazenados. A partir disso, parece que a minha pergunta é discutível.

No entanto isso não faz o que eu realmente queria saber discutível: Como você otimizar uma consulta que contém valores que são constantes dentro de qualquer consulta específica, mas onde eu, o programador, não conhecido de antemão o valor será usado -? Por exemplo, dizer que o meu código do lado do cliente está gerando uma consulta com um número dentro da cláusula where. Algumas vezes o número resultará em um cláusula impossível onde outras vezes não. Como posso usar explicar para examinar como bem otimizado a consulta é?

A melhor abordagem que eu estou vendo logo de cara seria executar EXPLAIN nele para a matriz completa de casos exist / não existe. Realmente isso não é uma solução muito boa como seria ao mesmo tempo difícil e erro propenso a fazer à mão.

Foi útil?

Solução

Por exemplo, dizer que o meu código do lado do cliente está gerando uma consulta com um número em que é onde cláusula.

Algumas vezes o número resultará em um impossível cláusula WHERE outras vezes não.

Como posso usar explicar para examinar como bem otimizado a consulta é?

MySQL constrói planos de consulta diferentes para diferentes valores dos parâmetros vinculados.

Neste artigo você pode ler o lista de quando é que o otimizador MySQL faz o:

    Action                                      When

    Query parse                                 PREPARE
    Negation elimination                        PREPARE
    Subquery re-writes                          PREPARE

    Nested JOIN simplification                  First EXECUTE
    OUTER->INNER JOIN conversions               First EXECUTE

    Partition pruning                           Every EXECUTE
    COUNT/MIN/MAX elimination                   Every EXECUTE
    Constant subexpression removal              Every EXECUTE
    Equality propagation                        Every EXECUTE
    Constant table detection                    Every EXECUTE
    ref access analysis                         Every EXECUTE
    range/index_merge analysis and optimization Every EXECUTE
    Join optimization                           Every EXECUTE

Há mais uma coisa que falta nesta lista.

MySQL pode reconstruir um plano de consulta em todas as JOIN iteração :. Tal chamado range checking for each record

Se você tem um índice composto sobre uma mesa:

CREATE INDEX ix_table2_col1_col2 ON table2 (col1, col2)

e uma consulta como esta:

SELECT  *
FROM    table1 t1
JOIN    table2 t2
ON      t2.col1 = t1.value1
        AND t2.col2 BETWEEN t1.value2_lowerbound AND t2.value2_upperbound

, MySQL não vai usar um acesso de índice RANGE de (t1.value1, t1.value2_lowerbound) para (t1.value1, t1.value2_upperbound). Em vez disso, ele usará um acesso de índice REF em (t1.value) e filtro apenas os valores errados.

Mas se você reescrever a consulta como esta:

SELECT  *
FROM    table1 t1
JOIN    table2 t2
ON      t2.col1 <= t1.value1
        AND t2.col1 >= t2.value1
        AND t2.col2 BETWEEN t1.value2_lowerbound AND t2.value2_upperbound

, em seguida, MySQL irá verificar novamente o acesso índice RANGE para cada registro de table1 , e decidir se a utilização de acesso RANGE na mosca.

Você pode ler sobre isso nestes artigos no meu blog:

Todas essas coisas empregar RANGE CHECKING FOR EACH RECORD

Voltando à sua pergunta:. não há nenhuma maneira de saber qual plano irá MySQL uso para cada dado constante, já que não há nenhum plano antes da constante é dado

Infelizmente, não há nenhuma maneira de forçar MySQL usar um plano de consulta para cada valor de um parâmetro de limite.

Você pode controlar a ordem JOIN e INDEX'es ser escolhido usando cláusulas STRAIGHT_JOIN e FORCE INDEX, mas eles não vão forçar um certo caminho de acesso em um índice ou proibir a IMPOSSIBLE WHERE.

Por outro lado, para todos da JOIN, MySQL emprega apenas NESTED LOOPS. Isso significa que se você construir fim JOIN direita ou escolher índices certas, MySQL provavelmente beneficiar de tudo de IMPOSSIBLE WHERE.

Outras dicas

Você está recebendo "Impossível ONDE notado" porque o valor especificado não é na coluna, não apenas porque é uma constante. Você poderia 1) use um valor que existe na coluna ou 2) apenas dizer col = col:

explain select cols from tbl where col = col;

Como você otimizar uma consulta com os valores que são constantes apenas para a consulta, mas onde eu, o programador, não sabe de antemão o valor será usado?

Ao usar índices nas colunas específicas (ou mesmo à combinação de colunas, se você sempre consultar as colunas dadas juntos). Se você tiver índices, o planejador de consultas será potencialmente usá-los.

Em relação aos valores "impossíveis": o planejador de consulta pode-se concluir que um determinado valor não está na tabela de várias fontes:

  • se existe um índice para a coluna particular, pode-se observar que o valor particular é grande ou menor do que todo o valor do índice (mínimo de valores max / ter tempo constante a partir de extracto de índices)
  • se você estiver passando no tipo errado (se você está pedindo uma coluna numérica para ser igual a um texto)

PS. Em geral, a criação do plano de consulta não é caro e é melhor para re-criar do que para reutilizá-los, uma vez que as condições podem ter mudado desde o plano de consulta foi gerado e existe um melhor poder plano de consulta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top