我有一个非常大的地理LINESTRING
数据表,我要从 Oracle 移动到 SQL Server。在 Oracle 中有许多针对此数据执行的评估,并且它们也需要针对 SQL Server 中的数据执行。
问题:SQL Server 对有效的要求LINESTRING
比 Oracle更严格;“LineString 实例不能在两个或多个连续点的间隔内重叠”。 碰巧我们的LINESTRING
s的百分比不符合该标准,这意味着我们需要评估数据的函数失败。我需要调整数据,以便它可以在 SQL Server 中成功验证。
例如:
验证一个非常简单的LINESTRING
自我加倍:
select geography::STGeomFromText(
'LINESTRING (0 0 1, 0 1 2, 0 -1 3)',4326).IsValidDetailed()
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)24413: Not valid because of two overlapping edges in curve (1).
MakeValid
针对它执行函数:
select geography::STGeomFromText(
'LINESTRING (0 0 1, 0 1 2, 0 -1 3)',4326).MakeValid().STAsText()
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)LINESTRING (0 -0.999999999999867, 0 0, 0 0.999999999999867)
不幸的是,该MakeValid
函数更改了点的顺序并删除了第三维,这使我们无法使用它。我正在寻找另一种无需重新排序或删除第三维即可解决此问题的方法。
有任何想法吗?
我的实际数据包含数百/数千个点。
此查询在 ~21 秒内运行(执行计划):
select
a.month
, count(*)
from SubqueryTest a
where a.year = (select max(b.year) from SubqueryTest b)
group by a.month
Run Code Online (Sandbox Code Playgroud)
当子查询被变量替换时,它会在 <1 秒内运行(执行计划):
declare @year float
select @year = max(b.year) from SubqueryTest b
select
month
, count(*)
from SubqueryTest where year = @year group by month
Run Code Online (Sandbox Code Playgroud)
从执行计划来看,“select max...”子选择对“SubqueryTest a:”中的数百万行中的每一行都运行,这就是为什么它需要这么长时间。
我的问题:由于子选择是标量、确定性且不相关,为什么查询优化器不执行我在第二个示例中所做的操作并运行子查询一次,存储结果,然后将其用于主查询?我确定我对 SQL Server 的理解只是一个漏洞,但我真的很想帮助填补它 - 用谷歌几个小时没有帮助。
该表刚超过 1GB,有近 2800 万条记录:
CREATE TABLE SubqueryTest(
[pk_id] [int] IDENTITY(1,1) NOT NULL
, [Year] [float] NULL
, [Month] [float] NULL …
Run Code Online (Sandbox Code Playgroud) 从我在线阅读的内容来看,与在单个文件组中包含多个文件相比,多个文件组似乎只有两个优势:
能够将特定表隔离到特定驱动器 - 实现此目的的唯一方法是在目标驱动器上添加一个包含文件的新文件组,然后将表移到那里。
可以通过使用只读文件组进行零碎恢复来加快恢复速度。
与单个文件组中的多个文件相比,多个文件组还有其他优势吗?我对性能优势最感兴趣,但欢迎任何想法。