Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Cálculo de distância com enorme banco de dados SQL Server


Você poderia fazer pior do que olhar para a GEOGRAPHY tipo de dados, por exemplo:
CREATE TABLE Places
(
    SeqID       INT IDENTITY(1,1),
    Place       NVARCHAR(20),
    Location    GEOGRAPHY
)
GO
INSERT INTO Places (Place, Location) VALUES ('Coventry', geography::Point(52.4167, -1.55, 4326))
INSERT INTO Places (Place, Location) VALUES ('Sheffield', geography::Point(53.3667, -1.5, 4326))
INSERT INTO Places (Place, Location) VALUES ('Penzance', geography::Point(50.1214, -5.5347, 4326))
INSERT INTO Places (Place, Location) VALUES ('Brentwood', geography::Point(52.6208, 0.3033, 4326))
INSERT INTO Places (Place, Location) VALUES ('Inverness', geography::Point(57.4760, -4.2254, 4326))
GO
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
    FROM Places p1
    CROSS JOIN Places p2
GO  
SELECT p1.Place, p2.place, p1.location.STDistance(p2.location) / 1000 AS DistanceInKilometres
    FROM Places p1
        INNER JOIN Places p2 ON p1.SeqID > p2.SeqID
GO  

geography::Point leva a latitude e longitude, bem como um SRID (número de ID de referência especial). Nesse caso, o SRID é 4326, que é latitude e longitude padrão. Como você já tem latitude e longitude, basta ALTER TABLE para adicionar a coluna de geografia, então UPDATE para povoá-lo.

Mostrei duas maneiras de obter os dados da tabela, mas você não pode criar uma exibição indexada com isso (as exibições indexadas não podem ter autojunções). No entanto, você pode criar uma tabela secundária que seja efetivamente um cache, preenchida com base no acima. Você então só precisa se preocupar em mantê-lo (pode ser feito através de gatilhos ou algum outro processo).

Observe que a junção cruzada fornecerá 250.000.000.000 linhas, mas a pesquisa é simples, pois você só precisa olhar para uma das colunas de lugares (ou seja, SELECT * FROM table WHERE Place1 = 'Sheffield' AND distance < 100 , o segundo fornecerá significativamente menos linhas, mas a consulta precisará considerar as colunas Place1 e Place2).