我想查找以在搜索框中输入的字符开头的地理名称。一些地理名称在其他语言中有替代名称。这些替代名称存储在单独的表中。
GN_Name 1 - 0:N GN_AlternateName
(PK)GN_Name.GeoNameId == (FK)GN_AlternateName.GeoNameId
我想先在 GN_AlternateName.AlternateName 中搜索名称,如果不存在,请使用相应的 GN_Name.Name。
我写了以下 LINQ 查询:
return (from name in db.GN_Name
where name.CountryCode == "se"
join alt in db.GN_AlternateName
on name.GeoNameId equals alt.GeoNameId into outer
from alt in outer.DefaultIfEmpty()
where ((alt.IsoLanguage == "sv" &&
alt.AlternateName.StartsWith(query)) ||
name.Name.StartsWith(query))
select new GeoNameModel {
Language = alt.IsoLanguage,
Name = (alt == null ? name.Name : alt.AlternateName),
FeatureClass = name.FeatureClass,
FeatureCode = name.FeatureCode,
GeoNameId = name.GeoNameId,
UniqueName = name.UniqueName,
UniqueCount = name.UniqueCount}).Take(HB.AutoCompleteCount);
这转化为以下 SQL:
exec sp_executesql N'SELECT
[Limit1].[GeoNameId] AS [GeoNameId],
[Limit1].[IsoLanguage] AS [IsoLanguage],
[Limit1].[C1] AS [C1],
[Limit1].[FeatureClass] AS [FeatureClass],
[Limit1].[FeatureCode] AS [FeatureCode],
[Limit1].[UniqueName] AS [UniqueName],
[Limit1].[UniqueCount] AS [UniqueCount]
FROM ( SELECT TOP (5)
[Extent1].[GeoNameId] AS [GeoNameId],
[Extent1].[FeatureClass] AS [FeatureClass],
[Extent1].[FeatureCode] AS [FeatureCode],
[Extent1].[UniqueName] AS [UniqueName],
[Extent1].[UniqueCount] AS [UniqueCount],
CASE WHEN ([Extent2].[AlternateNameId] IS NULL) THEN [Extent1].[Name] ELSE [Extent2].[AlternateName] END AS [C1],
[Extent2].[IsoLanguage] AS [IsoLanguage]
FROM [dbo].[GN_Name] AS [Extent1]
LEFT OUTER JOIN [dbo].[GN_AlternateName] AS [Extent2] ON [Extent1].[GeoNameId] = [Extent2].[GeoNameId]
WHERE (''se'' = [Extent1].[CountryCode]) AND (((''sv'' = [Extent2].[IsoLanguage]) AND ([Extent2].[AlternateName] LIKE @p__linq__0 ESCAPE N''~'')) OR ([Extent1].[Name] LIKE @p__linq__1 ESCAPE N''~''))
) AS [Limit1]',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'ja%',@p__linq__1=N'ja%'
我真的看不出它有什么问题,但大约需要 5 秒才能完成。
我应该添加一些索引吗?也许设置一个索引视图?我的 SQL 服务器知识有限,我很想回到一些真正的编码;)
任何建议热烈赞赏!
更新 我正在使用 SQL Server 2008。按照 taylonr 的说明,我得到了以下结果。
有 3 个“部分”占总数的 100%。但是,我不知道如何使用这些统计数据。
更新 2
SSMS 执行计划推荐以下指标:
CREATE NONCLUSTERED INDEX IX_GN_Name_CountryCode
ON [dbo].[GN_Name] ([CountryCode])
INCLUDE ([GeoNameId],[Name],[FeatureClass],[FeatureCode],[UniqueName],[UniqueCount])
我添加了它,现在查询运行得更好了!
UPDATE 3 taylonr 建议只使用一个 LIKE 子句。我不确定如何做到这一点。有人愿意挑战吗?