Я работаю над перемещением некоторых возможностей пространственного поиска из Postgres с PostGIS на SQL Server, и я вижу довольно ужасную производительность даже с индексами.Почему мои пространственные запросы медленнее в SQL Server, чем PostGIS?
Мои данные около миллиона точек, и я хочу, чтобы выяснить, какие из этих точек в пределах заданной формы, поэтому запрос выглядит следующим образом:
DECLARE @Shape GEOMETRY = ...
SELECT * FROM PointsTable WHERE Point.STWithin(@Shape) = 1
Если я выбираю довольно небольшую форму, Иногда я могу получить второстепенное время, но если моя форма довольно большая (что они иногда есть), я могу получить время более 5 минут. Если я запускаю те же поисковые запросы в Postgres, они всегда находятся под второй (на самом деле, почти все составляют менее 200 мс).
Я пробовал несколько разных размеров сетки на моих индексах (все высокие, все средние, все низкие), разные ячейки на объект (16, 64, 256), и независимо от того, что я делаю, время остается довольно постоянным. Я хотел бы попробовать больше комбинаций, но я даже не знаю, в каком направлении идти. Больше клеток на объект? Меньше? Какое-то странное сочетание размеров сетки?
Я просмотрел мои планы запросов, и они всегда используют индекс, это просто не помогает вообще. Я даже пробовал без индекса, и это не намного хуже.
Есть ли какие-либо советы, которые кто-либо может дать по этому поводу? Все, что я могу найти, предлагает «мы не можем дать вам никаких советов по индексам, просто попробуйте все, и, возможно, один будет работать», но с этим требуется 10 минут для создания индекса, делая это вслепую - это огромная трата времени.
EDIT: Я также разместил это на a Microsoft forum. Вот некоторая информация, они попросили там:
Лучший рабочий индекс я мог бы получить это был один:
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
)
У меня были некоторые вопросы, получить индекс используется, но это другое.
Для этих тестов я провел тестовый поиск (тот, который указан в моем исходном сообщении) с предложением WITH (INDEX (...)) для каждого из моих индексов (тестирование различных параметров для размера сетки и ячеек на объект) , и один без намека. Я также запускал sp_help_spatial_geometry_index, используя каждый индекс и ту же форму поиска. Указанный выше индекс выполнялся быстрее всего и также был указан как наиболее эффективный в sp_help_spatial_geometry_index.
При выполнении поиска я получаю эту статистику:
(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.
Я также попытался с помощью случайных точек в качестве данных (так как я не могу дать наши реальные данные), но оказывается, что этот поиск действительно быстро со случайными данными. Это заставляет нас думать, что наша проблема заключается в том, как сетевая система работает с нашими данными.
Наши данные - это адреса по всему штату, поэтому есть несколько областей с очень высокой плотностью, но в основном с редкими данными. Я думаю, проблема заключается в том, что настройка параметров сетки не работает хорошо для обоих. С сетками, установленными в HIGH
, индекс возвращает слишком много ячеек в областях с низкой плотностью, а сетки, установленные на LOW
, сетки бесполезны в областях с высокой плотностью (в MEDIUM
, это не так плохо, но все равно не очень хорошо).
Я могу использовать индекс, это просто не помогает. Каждый тест запускался с включенным «показать фактический план выполнения», и он всегда показывает индекс.
+1: Я хотел бы также знать. –
Ваши миллионные данные хранятся в виде геометрии (плоское, евклидово пространство) или география (округлые, земные координаты)? Если вы смешиваете геометрию и географию, вы собираетесь ввести удар производительности для математики преобразования. – mwalker
@Mwalker, Это все геометрия, и я не думаю, что вы все равно можете смешивать и сопоставлять их. –