Estoy trabajando en mover algunas capacidades de búsqueda espacial de Postgres con PostGIS a SQL Server y estoy viendo un rendimiento bastante terrible, incluso con índices.¿Por qué mis búsquedas espaciales son más lentas en SQL Server que PostGIS?
Mis datos es de alrededor de un millón de puntos, y quiero averiguar cuál de estos puntos están dentro de formas dadas, por lo que la consulta es como la siguiente:
DECLARE @Shape GEOMETRY = ...
SELECT * FROM PointsTable WHERE Point.STWithin(@Shape) = 1
Si selecciono una bastante pequeña forma, A veces puedo obtener segundos segundos, pero si mi forma es bastante grande (que a veces son), puedo obtener tiempos de más de 5 minutos. Si ejecuto las mismas búsquedas en Postgres, siempre están por debajo de un segundo (de hecho, casi todas tienen menos de 200 ms).
He intentado varios tamaños de cuadrícula en mis índices (todos altos, todos medianos, todos bajos), diferentes celdas por objeto (16, 64, 256) y no importa lo que haga, los tiempos permanecen bastante constantes. Me gustaría probar más combinaciones, pero ni siquiera sé qué dirección tomar. Más celdas por objeto? ¿Menos? ¿Alguna extraña combinación de tamaños de cuadrícula?
He visto mis planes de consulta y siempre están usando el índice, simplemente no está ayudando en absoluto. Incluso he intentado sin el índice, y no es mucho peor.
¿Hay algún consejo que alguien pueda dar sobre esto? Todo lo que puedo encontrar sugiere que "no podemos darle ningún consejo sobre índices, simplemente pruebe todo y tal vez uno funcione", pero demorar 10 minutos en crear un índice, hacerlo a ciegas es una gran pérdida de tiempo.
EDITAR: También publiqué esto en a Microsoft forum. He aquí alguna información que pedían allí:
El mejor índice de trabajo que pude conseguir fue la siguiente:
CREATE SPATIAL INDEX MapTesting_Location_Medium_Medium_Medium_Medium_16_NDX
ON MapTesting (Location)
USING GEOMETRY_GRID
WITH (
BOUNDING_BOX = (-- The extent of our data, data is clustered in cities, but this is about as small as the index can be without missing thousands of points
XMIN = -12135832,
YMIN = 4433884,
XMAX = -11296439,
YMAX = 5443645),
GRIDS = (
LEVEL_1 = MEDIUM,
LEVEL_2 = MEDIUM,
LEVEL_3 = MEDIUM,
LEVEL_4 = MEDIUM),
CELLS_PER_OBJECT = 256 -- This was set to 16 but it was much slower
)
he tenido algunos problemas para conseguir el índice utilizado, pero esto es diferente.
Para estas pruebas realicé una búsqueda de prueba (la que figura en mi publicación original) con una cláusula WITH (INDEX (...)) para cada uno de mis índices (probando varias configuraciones para el tamaño de la cuadrícula y las celdas por objeto) y uno sin ninguna pista. También ejecuté sp_help_spatial_geometry_index usando cada índice y la misma forma de búsqueda. El índice mencionado anteriormente funcionaba más rápido y también se incluyó como el más eficaz en sp_help_spatial_geometry_index.
Cuando se ejecuta la búsqueda consigo estas estadísticas:
(1 row(s) affected)
Table 'MapTesting'. Scan count 0, logical reads 361142, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'extended_index_592590491_384009'. Scan count 1827, logical reads 8041, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 6735 ms, elapsed time = 13499 ms.
También he intentado usar como puntos aleatorios de datos (ya que no puedo dar a conocer nuestros datos reales), pero resulta que esta búsqueda es realmente rápido con datos aleatorios. Esto nos lleva a creer que nuestro problema es cómo funciona el sistema de cuadrícula con nuestros datos.
Nuestros datos son direcciones en todo el estado, por lo que hay algunas regiones de muy alta densidad, pero la mayoría de los datos son escasos. Creo que el problema es que ninguna configuración para los tamaños de cuadrícula funciona bien para ambos. Con cuadrículas establecidas en HIGH
, el índice devuelve demasiadas celdas en áreas de baja densidad, y con grillas establecidas en LOW
, las cuadrículas son inútiles en áreas de alta densidad (en MEDIUM
, no es tan malo, pero aún no es bueno en ninguno).
Puedo utilizar el índice, simplemente no está ayudando. Cada prueba se ejecutó con "mostrar plan de ejecución real" activado, y siempre muestra el índice.
+1: Me gustaría saber también. –
¿Están sus millones de puntos de datos almacenados como geometría (plana, espacio euclidiano) o geografía (coordenadas redondas y terrenales)? Si está mezclando geometría y geografía, va a introducir un golpe de rendimiento para la conversión matemática. – mwalker
@Mwalker, es todo geometría, y no creo que puedas mezclarlos y combinarlos de todos modos. –