【发布时间】:2018-05-12 22:11:44
【问题描述】:
我意识到在使用 Azure SQL 数据库时使用 EntityFramework 生成的参数化查询时的性能差异。
我有一个带有 varchar(30) 主键的表,当我尝试使用主键从该表中获取值时,EntityFramework 使用 NVARCHAR(4000) 作为数据类型创建参数化查询。
DECLARE @p__linq__0 nvarchar(4000)
SET @p__linq__0 ='ehenurqp0kpql76kjsw3'
select * from mediacontentreferences where mediacontentreferenceid=@p__linq__0
这会在 Azure SQL 数据库上生成一个非常奇怪的执行计划。
这是非常无效的,因为它使用了查看整个表的索引扫描。
如果我使用具有正确数据类型的参数,执行计划将使用主键索引。
DECLARE @p__linq__1 varchar(30)
SET @p__linq__1 ='ehenurqp0kpql76kjsw3'
select * from mediacontentreferences where mediacontentreferenceid=@p__linq__1
如果我在本地 SQL 服务器上使用第一个查询,执行计划会将 NVARCHAR(4000) 转换为 VARCHAR(30) 并使用主键索引。
这看起来像是 Azure SQL 服务器上的执行计划计算中的一个缺陷。
是否有可能改变实体框架创建查询的行为?
我已经阅读了几篇关于此的文章,但没有找到解决方案。
Why does code first/EF use 'nvarchar(4000)' for strings in the raw SQL command?
Why does Entity Framework generate large parameters? How can they be reduced?
【问题讨论】:
-
本地机器是什么版本的 SQL Server?
-
对列使用 hasmaxlength 设置? prashantbrall.wordpress.com/2011/04
-
在本地,已经测试了 2008 R2 和 2014,两者都有效
-
列的长度没有影响,但如果我将参数类型更改为 varchar(与列相同),无论长度如何,它都适用于 azure
-
我问的原因是因为 Azure 优化器更符合或稍微领先于 SQL Server 2017。因此,与 2014 年或更早的版本相比,Azure 的行为不会非常准确。
标签: sql-server entity-framework azure-sql-database