Recentemente, monitorei uma consulta lenta como esta:
Selecione Delete_flag, delete_timefrom d_orderinfo onde (OrderId não é nulo e OrderId = n'xxxx ')
Existe um índice de OrderId na tabela D_Orderinfo, mas o campo OrderId é do tipo varchar.
Como a estrutura de desenvolvimento MyBatis gera automaticamente a condição e não especifica o tipo de parâmetro, o parâmetro do tipo de sequência se tornará automaticamente o Nvarchar (4000) no SQLServer. O que é complicado é que está tudo bem se você não especificar o tipo de parâmetro, mas também adiciona automaticamente uma condição que não é de Sarg como o OrderId não é nula, e o plano de execução se torna assim:
-----------------------------------------------------------------------------------------------
Se não houver OrderId não for condição nula, o plano de execução será assim:
Como o tipo de parâmetro Nvarchar tem maior prioridade que o tipo de campo de índice VARCHAR, ele não pode ser convertido diretamente, mas o otimizador SQLServer eventualmente o converte em um valor de intervalo, e a consulta final de sinal igual se torna semelhante a uma consulta de pequena faixa.
Você pode ver a partir das informações detalhadas da busca de índices:
--------------------------------------------------------------------------
Se os tipos de parâmetros corresponderem, o plano de execução será o esperado (embora não incluído, ainda existe uma pesquisa importante):
Claro, a maneira como eu finalmente esperava escrever é a seguinte:
Selecione Delete_flag, Delete_timefrom d_orderinfo onde OrderId = 'xxxx'
O plano de execução será obviamente assim:
Mas, eu simplesmente não sei para que o mestre de desenvolvimento pode mudar no final ...
A solução do Mestre do Desenvolvimento: Configure a sequência de conexão:
SendStringParameterSAsunicode = false
PostScript:
Por padrão, os dados do caractere em Java são processados como unicode; Os objetos de string java representam dados de caracteres Unicode. Nos drivers JDBC, as únicas coisas que não podem obedecer a essa regra são os métodos ASCII Stream Getter e Setter, que são casos especiais porque os fluxos de bytes usados por esses métodos carregam a suposição implícita de uma única página de código conhecida (ASCII).
Além disso, o driver JDBC fornece a propriedade SendStringParametersAsunicode Connection String. Esta propriedade pode ser usada para especificar parâmetros predefinidos para dados de caracteres enviados como ASCII em vez de unicode.
Como aprimoramento de desempenho, o parâmetro String pode ser passado para o SQL Server em um formato não unicode, definindo a propriedade SendStringParameterSAsunicode Connection String. A configuração padrão do SendStringParameterSAsunicode é "true", o que significa que o parâmetro da string será enviado como Unicode.
Se o SendStringParameterSAsunicode estiver definido como "false", todos os parâmetros da string na conexão serão enviados ao servidor usando o conjunto padrão do banco de dados.
Consulte:
http://d.hatena.ne.jp/gnarl/20110706/1309945379
https://technet.microsoft.com/zh-cn/library/ms378857(sql.90).aspx
https://technet.microsoft.com/zh-cn/library/ms378988(v=sql.90).aspx