Recientemente, he monitoreado una consulta lenta como esta:
Seleccione Delete_Flag, Delete_TimeFrom D_OrderInfo Where (OrderId no es nulo y ordenid = n'xxxx ')
Hay un índice de ordenid en la tabla D_orderInfo, pero el campo OrderId es de tipo varchar.
Dado que el marco de desarrollo myBatis genera automáticamente la condición Where y no especifica el tipo de parámetro, el parámetro del tipo de cadena se convertirá automáticamente en nvarchar (4000) en SQLServer. Lo complicado es que está bien si no especifica el tipo de parámetro, pero también agrega automáticamente una condición no sarg como OrderId no es nulo, y el plan de ejecución se vuelve así:
---------------------------------------------------------------------------------------------
Si no hay ordenid no es una condición nula, el plan de ejecución será así:
Dado que el tipo de parámetro NVARCHAR tiene una prioridad más alta que el tipo de campo de índice VARCHAR, no se puede convertir directamente, pero el optimizador SQLServer finalmente lo convierte en un valor de rango, y la consulta de signo igual final se vuelve similar a una pequeña consulta de rango.
Puede ver desde la información detallada de la búsqueda del índice:
------------------------------------------------------------------------
Si los tipos de parámetros coinciden, el plan de ejecución será como se esperaba (aunque no incluido, todavía hay una búsqueda clave):
Por supuesto, la forma en que finalmente esperaba escribir es la siguiente:
Seleccione Delete_Flag, Delete_TimeFrom D_OrderInfo Where OrderId = 'xxxx'
El plan de ejecución, por supuesto, será así:
Pero, simplemente no sé a qué puede cambiar el maestro de desarrollo al final ...
La solución del maestro de desarrollo: configure la cadena de conexión:
sendStringParametersAsunicode = False
posdata:
Por defecto, los datos de caracteres en Java se procesan como unicode; Los objetos de cadena Java representan datos de caracteres Unicode. En los controladores JDBC, las únicas cosas que no pueden obedecer esta regla son los métodos de Getter y Setter ASCII, que son casos especiales porque las corrientes de bytes utilizadas por estos métodos conllevan la suposición implícita de una sola página de código conocido (ASCII).
Además, el controlador JDBC proporciona la propiedad SendStringParametersAsunicode Connection String. Esta propiedad se puede utilizar para especificar parámetros predefinidos para los datos de caracteres enviados como ASCII en lugar de unicode.
Como mejora del rendimiento, el parámetro de cadena se puede pasar al servidor SQL en un formato no unicode configurando la propiedad SendStringParametersUsunicode Connection String. La configuración predeterminada de SendStringParametersAsunicode es "verdadera", lo que significa que el parámetro de cadena se enviará como unicode.
Si SendStringParametersUnicode se establece en "False", todos los parámetros de cadena en la conexión se envían al servidor utilizando la recopilación predeterminada de la base de datos.
referirse a:
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