我有下表:
CREATE TABLE [dbo].[CollectionSite](
[SiteCode] [nvarchar](32) NOT NULL,
[AddressId] [int] NOT NULL,
//...
[Location] [geography] NOT NULL,
表具有大约10000条记录。
我有以下linq查询:
var list = dataContext.CollectionSites.Where(p => p.Location.Distance(myLocation)<3000000).OrderBy(p => p.Location.Distance(myLocation))
.ToList();
执行时间约为12-15秒。然后,我尝试创建一个空间索引:
CREATE SPATIAL INDEX SIX_CollectionSite_SiteCode ON CollectionSite([Location]) USING GEOGRAPHY_GRID
它创建成功。但是执行时间是相同的。为什么索引不起作用?
EF Core的版本为2.2.4
添加01/01/2020
它生成以下sql:
exec sp_executesql N'SELECT [p].[SiteCode], [p].[AddressId], [p].[Location]
FROM [CollectionSite] AS [p]
WHERE [p].[Location].STDistance(@__myLocation_0) < 3000000.0E0
ORDER BY [p].[Location].STDistance(@__myLocation_0)',N'@__myLocation_0 varbinary(22)',@__myLocation_0=0xE6100000010C0403081F4ACA4040ACADD85F76FB5BC0
并从.NET应用执行了12-15秒,但直接不到1秒
下一步。我将时间标记添加到以下位置:
var query = dataContext.CollectionSites
.Where(p => p.Location.Distance(myLocation) < 3000000)
.OrderBy(p => p.Location.Distance(myLocation))
.Select(p => new { p.SiteCode, p.AddressId, p.Location })
;
var ms11 = sw.ElapsedMilliseconds;
var list = query.ToList();
而这个ms11有这12到15秒,ToList()执行时间不到1秒!为什么查询组合这么长时间?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
发生了其他事情。试试这个简单的复制。它在1秒内搜索10000个地理结果,而没有空间索引。有了空间索引,它甚至更快。
using Microsoft.EntityFrameworkCore;
using Microsoft.Samples.EFLogging;
using NetTopologySuite;
using NetTopologySuite.Geometries;
using System;
using System.Diagnostics;
using System.Linq;
namespace EfTest
{
public class CollectionSite
{
public int Id { get; set; }
public string SiteCode { get; set; }
public int AddressId { get; set; }
public Geometry Location { get; set; }
}
public class Db : DbContext
{
private string connectionString;
public Db() : this("Server=.;Database=EfCoreTest;Integrated Security=true")
{
}
public Db(string connectionString)
{
this.connectionString = connectionString;
}
public DbSet<CollectionSite> CollectionSites { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(connectionString, b => b.UseRelationalNulls().UseNetTopologySuite());
base.OnConfiguring(optionsBuilder);
}
}
public class Program
{
static void Main(string[] args)
{
var gf = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
using (var db = new Db())
{
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
}
using (var db = new Db())
{
for (int i = 0; i < 10000; i++)
{
var loc = new CollectionSite()
{
Location = gf.CreatePoint(new Coordinate(-90 + i / 1000.0, 45 + i / 1000.0)),
AddressId = i,
SiteCode = "site" + i
};
db.CollectionSites.Add(loc);
}
db.SaveChanges();
}
using (var db = new Db())
{
db.ConfigureLogging( s => Console.WriteLine(s));
var myLocation = gf.CreatePoint(new Coordinate(-90, 45));
var sw = new Stopwatch();
sw.Start();
var list = db.CollectionSites
.Where(p => p.Location.Distance(myLocation) < 30000)
.OrderBy(p => p.Location.Distance(myLocation))
.ToList();
Console.WriteLine($"Found {list.Count} sites in {sw.ElapsedMilliseconds}ms");
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}
}
输出
Found 221 sites in 982ms
Hit any key to exit
它生成的查询是:
SELECT [c].[Id], [c].[AddressId], [c].[Location], [c].[SiteCode]
FROM [CollectionSites] AS [c]
WHERE [c].[Location].STDistance(@__myLocation_0) < 3000.0E0
ORDER BY [c].[Location].STDistance(@__myLocation_0)