【发布时间】:2019-06-29 14:49:14
【问题描述】:
EF 创建了一个使用索引扫描而不是索引搜索的查询。通过稍微修改查询以不使用参数,而是使用索引查找。索引扫描大约需要 3 秒,而 Seek 是即时的。
生成的查询(使用索引扫描):
exec sp_executesql N'SELECT TOP (1)
[Extent1].[phone_id] AS [phone_id],
[Extent1].[phone] AS [phone],
[Extent1].[high_usage_flag] AS [high_usage_flag],
[Extent1].[cds_flag] AS [cds_flag],
[Extent1].[never_call_flag] AS [never_call_flag],
[Extent1].[pa_state_dnc_flag] AS [pa_state_dnc_flag],
[Extent1].[ma_state_dnc_flag] AS [ma_state_dnc_flag],
[Extent1].[national_dnc_flag] AS [national_dnc_flag],
[Extent1].[note] AS [note],
[Extent1].[pec_never_call_flag] AS [pec_never_call_flag],
[Extent1].[nicor_dnc_flag] AS [nicor_dnc_flag],
[Extent1].[css_vici_flag] AS [css_vici_flag],
[Extent1].[css_pec_flag] AS [css_pec_flag],
[Extent1].[css_vici_alt_flag] AS [css_vici_alt_flag],
[Extent1].[area_code] AS [area_code],
[Extent1].[phone_type_id] AS [phone_type_id],
[Extent1].[last_answer_date] AS [last_answer_date],
[Extent1].[csr_bad_flag] AS [csr_bad_flag],
[Extent1].[to_process_flag] AS [to_process_flag],
[Extent1].[deleted_date] AS [deleted_date],
[Extent1].[wireless_flag] AS [wireless_flag]
FROM [dbo].[phone] AS [Extent1]
WHERE [Extent1].[phone] = @p__linq__0',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'555555555'
修改为不使用参数(使用索引查找):
exec sp_executesql N'SELECT TOP (1)
[Extent1].[phone_id] AS [phone_id],
[Extent1].[phone] AS [phone],
[Extent1].[high_usage_flag] AS [high_usage_flag],
[Extent1].[cds_flag] AS [cds_flag],
[Extent1].[never_call_flag] AS [never_call_flag],
[Extent1].[pa_state_dnc_flag] AS [pa_state_dnc_flag],
[Extent1].[ma_state_dnc_flag] AS [ma_state_dnc_flag],
[Extent1].[national_dnc_flag] AS [national_dnc_flag],
[Extent1].[note] AS [note],
[Extent1].[pec_never_call_flag] AS [pec_never_call_flag],
[Extent1].[nicor_dnc_flag] AS [nicor_dnc_flag],
[Extent1].[css_vici_flag] AS [css_vici_flag],
[Extent1].[css_pec_flag] AS [css_pec_flag],
[Extent1].[css_vici_alt_flag] AS [css_vici_alt_flag],
[Extent1].[area_code] AS [area_code],
[Extent1].[phone_type_id] AS [phone_type_id],
[Extent1].[last_answer_date] AS [last_answer_date],
[Extent1].[csr_bad_flag] AS [csr_bad_flag],
[Extent1].[to_process_flag] AS [to_process_flag],
[Extent1].[deleted_date] AS [deleted_date],
[Extent1].[wireless_flag] AS [wireless_flag]
FROM [dbo].[phone] AS [Extent1]
WHERE [Extent1].[phone] = ''5555555555'''
谁能告诉我这里发生了什么以及如何让 Linq 使用索引?
【问题讨论】:
-
LINQ 对于除了简单查询之外的任何事情都非常糟糕。我已经看到 LINQ 将 4 个带有 where 条件的表连接翻译成可怕的、执行时间很长的 TSQL 代码。您可以尝试在 SQL Server 中将查询创建为视图或过程,并让代码调用查询或过程。
-
phone.phone的数据类型是什么?
-
@DavidBrowne-Microsoft,您走在正确的轨道上。原来数据类型是varchar,而不是nvarchar,所以没有使用索引
标签: sql-server entity-framework entity-framework-core