fre*_*ito 6 sql-server spatial sql-server-2014
我们刚刚从 SQL Server 2008 升级到 2014。除了我们在空间索引上遇到的问题之外,它进行得相当顺利。在这张桌子上,我们收到错误
无法在具有唯一索引“lu_unit__geolocation”的对象“sys.extended_index_1527780600_384000”中插入重复的键行。- 重复键值:(0x20330a3504, 95469304)。
空间索引不能有唯一约束,有问题。
我认为更安全的方法是重建索引。我做了一些实验,我发现在 160 万行上重建索引大约需要 50 秒。生产表大约有 550 万行,由于无法在线构建空间索引,因此在无法访问基表时至少需要 3 分钟。
有没有人有在最短的停机时间内重建空间索引的经验?我们可以用 30 秒但不能用 3 分钟。
该解决方案的概念是准备具有相同结构的数据副本,并使用 与原始表交换sp_rename
。表结构的其他大变化也基本相同。
让我们创建表并用几何数据填充它。
CREATE TABLE SpatialTable (id int IDENTITY(1,1) primary key, geometry_col geometry);
CREATE SPATIAL INDEX SIndx_SpatialTable_geometry_col1
ON SpatialTable(geometry_col)
WITH ( BOUNDING_BOX = ( 0, 0, 500, 200 ) );
GO
INSERT INTO SpatialTable (geometry_col)
SELECT TOP 1000000 geometry::STGeomFromText('LINESTRING (100 100, 20 180, 180 180)', 0)
FROM sys.all_columns a,sys.all_columns b;
GO
Run Code Online (Sandbox Code Playgroud)
创建数据副本并准备适当的索引。这些操作不会损害原始表,并且除了空间索引创建之外应该很快。
SELECT * INTO SpatialTable2 FROM SpatialTable
GO
ALTER TABLE SpatialTable2 ADD CONSTRAINT PK_SpatialTable_Id PRIMARY KEY CLUSTERED (id);
GO
CREATE SPATIAL INDEX SIndx_SpatialTable_geometry_col1
ON SpatialTable2(geometry_col)
WITH ( BOUNDING_BOX = ( 0, 0, 500, 200 ) );
GO
Run Code Online (Sandbox Code Playgroud)
现在让我们在基表上模拟一些插入。
INSERT INTO SpatialTable (geometry_col)
SELECT TOP 1000 geometry_col FROM SpatialTable
Run Code Online (Sandbox Code Playgroud)
下面是一个只需要很短时间的技巧。
BEGIN TRANSACTION
SET IDENTITY_INSERT dbo.SpatialTable2 ON
INSERT INTO SpatialTable2 (id,geometry_col)
SELECT id,geometry_col FROM SpatialTable sp WITH (TABLOCKX)
WHERE NOT EXISTS (SELECT ID FROM SpatialTable2 sp2 where sp2.id=sp.id)
SET IDENTITY_INSERT dbo.SpatialTable2 OFF
EXEC sp_rename 'dbo.SpatialTable', 'SpatialTable_old';
EXEC sp_rename 'dbo.SpatialTable2', 'SpatialTable';
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud)
现在我们有了新表和新空间索引结构以及旧数据。当然,这只是步骤的建议,您应该将其应用于您的需求和数据结构,特别是更新和删除操作(如果它们发生在您的情况下)。
执行此操作后,您可以删除旧表以清理数据库或将其用于任何其他目的。
归档时间: |
|
查看次数: |
1026 次 |
最近记录: |