Récemment, j'ai surveillé une requête lente comme ceci:
Sélectionnez Delete_Flag, Delete_timeFrom D_OrderInfo où (OrderId n'est pas nul et ordonnance = nexxxx ')
Il y a un index de OrderID sur la table D_OrderInfo, mais le champ OrderID est de type Varchar.
Étant donné que le cadre de développement MyBatis génère automatiquement la condition où et ne spécifie pas le type de paramètre, le paramètre du type de chaîne deviendra automatiquement nvarchar (4000) dans SQLServer. Ce qui est difficile, c'est que c'est bien si vous ne spécifiez pas le type de paramètre, mais vous ajoutez également automatiquement une condition non sargée comme OrderId n'est pas nul, et le plan d'exécution devient ceci:
---------------------------------------------------------------------------------------------
S'il n'y a pas d'orderId n'est pas une condition nul, le plan d'exécution sera comme ceci:
Étant donné que le type de paramètre Nvarchar a une priorité plus élevée que le type de champ d'index varchar, il ne peut pas être converti directement, mais l'optimiseur SQLServer le convertit finalement en valeur de plage, et la requête de signe égale finale devient similaire à une requête à petite plage.
Vous pouvez voir dans les informations détaillées de la recherche d'index:
------------------------------------------------------------------------
Si les types de paramètres correspondent, le plan d'exécution sera comme prévu (bien qu'il ne soit pas inclus, il y a toujours une recherche de clé):
Bien sûr, la façon dont j'espérais finalement écrire est la suivante:
Sélectionnez Delete_Flag, Delete_timeFrom D_OrderInfo Where OrderID = 'XXXX'
Le plan d'exécution sera bien sûr comme ceci:
Mais, je ne sais pas à quoi le maître de développement peut changer à la fin ...
La solution du maître du développement: configurer la chaîne de connexion:
sendStringParametersAsUnicode = false
PostScript:
Par défaut, les données de caractère dans Java sont traitées comme Unicode; Les objets de chaîne Java représentent les données de caractères Unicode. Dans les pilotes JDBC, les seules choses qui ne peuvent pas obéir à cette règle sont les méthodes ASCII Stream Getter et Setter, qui sont des cas spéciaux car les flux d'octets utilisés par ces méthodes portent l'hypothèse implicite d'une seule page de code connue (ASCII).
De plus, le pilote JDBC fournit la propriété SendStringParametersaSunicode Connection String. Cette propriété peut être utilisée pour spécifier des paramètres prédéfinis pour les données de caractère envoyées comme ASCII au lieu d'Unicode.
En tant qu'amélioration des performances, le paramètre de chaîne peut être transmis à SQL Server dans un format non Unicode en définissant la propriété SendStringParametersaSunicode Connection. Le paramètre par défaut de SendStringParametersAsUnicode est "vrai", ce qui signifie que le paramètre de chaîne sera envoyé sous le nom de Unicode.
Si SendStringParametersAsUnicode est défini sur "FALSE", tous les paramètres de chaîne sur la connexion sont envoyés au serveur à l'aide de la collation par défaut de la base de données.
se référer à:
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