我正在运行带有字符串参数的简单grails查询。当查看在SQL Server事件探查器中生成的查询时,该查询将强制从nvarchar隐式转换为varchar,这会导致性能问题。
简单Grails查询:
Book.findByTitle("To Catch A Mocking Bird")
图书网域:
class Book {
String title
Date dateCreated
Date lastUpdated
static constraints = {
}
}
SQL表列(由Grails生成):
<table>
<thead>
<tr>
<th>table_name</th>
<th>column_name</th>
<th>data_type</th>
</tr>
</thead>
<tbody>
<tr>
<td>book</td>
<td>id</td>
<td>bigint</td>
</tr>
<tr>
<td>book</td>
<td>version</td>
<td>bigint</td>
</tr>
<tr>
<td>book</td>
<td>date_created</td>
<td>datetime2</td>
</tr>
<tr>
<td>book</td>
<td>last_updated</td>
<td>datetime2</td>
</tr>
<tr>
<td>book</td>
<td>title</td>
<td>varchar</td>
</tr>
</tbody>
</table>
在分析器中查询:
declare @p1 int
set @p1=5
exec sp_prepexec @p1 output,N'@P0 int,@P1 nvarchar(4000)',N'/* criteria query */ select TOP(@P0) this_.id as id1_24_0_, this_.version as version2_24_0_, this_.title as title3_24_0_, this_.date_created as date_cre5_24_0_, this_.last_updated as last_upd7_24_0_, from book this_ where this_.title=@P1 ',1,N'To Catch A Mocking Bird'
select @p1
请注意,该参数是字符串“捕获模拟鸟”]表“标题”列的类型为“ varchar”sp_prepexec语句将参数字符串作为nvarchar(4000)。这导致隐式转换,可能会产生负面的性能问题。
由于查询语句是由Grails中的GORM / Hibernate生成的,所以我无法控制查询语句的创建。
这是一个错误,还是需要设置一些配置以便该语句使用varchar而不是nvarchar?
环境:
您应该配置JDBC驱动程序。默认情况下,字符串参数将以Unicode格式发送到数据库服务器,因此,如果未在连接URL中配置字符串参数,它将以VARCHAR
的形式发送NVARCHAR
参数值。
在数据源配置中将sendStringParametersAsUnicode
参数设置为false
。更多信息here。