#sql #oracle #oracle-spatial
#sql #Oracle #oracle-пространственный
Вопрос:
У меня есть таблица MY_TABLE в oracle с пространственным индексом MY_IDX и около 22000 строк. Следующий запрос выполняется менее чем за ~ 500 мс и возвращает ~ 2600 результатов.
SELECT /* INDEX (MY_TABLE MY_IDX) */ ID,GEOM,LABEL FROM MY_TABLE
where (
(sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
'querytype=WINDOW')='TRUE')
);
Когда я добавляю предложение «ИЛИ» с другим пространственным фильтром, выполнение запроса занимает ~ 30 секунд, потребляя значительно больше процессора, чем следовало бы:
SELECT /* INDEX (MY_TABLE MY_IDX) */ ID,GEOM,LABEL FROM MY_TABLE
where (
(sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
'querytype=WINDOW')='TRUE')
OR
(sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(157.0,-48.0,180.0,32.0)),
'querytype=WINDOW')='TRUE')
);
Планы объяснения запросов сильно отличаются — первый показывает, что доступ к таблице осуществляется «ПО ИНДЕКСУ ROWID», где, поскольку второй «ПОЛНЫЙ». Есть ли способ заставить второй запрос выполняться аналогично первому?
v$version возвращает:
Oracle Database 11g Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
"CORE 11.2.0.1.0 Production"
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
Кстати, другая БД, работающая под управлением oracle enterprise edition, создает план, в котором используется индекс и объединяются результаты. Можно ли это сделать с помощью standard edition?
Ответ №1:
Преломление запроса с использованием внутреннего запроса и объединения, казалось, заставило oracle использовать индексы, как ожидалось:
SELECT ID,GEOM,LABEL FROM MY_TABLE
WHERE ID IN (
(SELECT ID FROM MY_TABLE WHERE sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(-180.0,-48.0,-67.0,32.0)),
'querytype=WINDOW')='TRUE')
UNION ALL
(SELECT ID FROM MY_TABLE WHERE sdo_filter(GEOM, mdsys.sdo_geometry(2003,8307,NULL,
mdsys.sdo_elem_info_array(1,1003,3),
mdsys.sdo_ordinate_array(157.0,-48.0,180.0,32.0)),
'querytype=WINDOW')='TRUE')
);
Ответ №2:
«Кстати, другая БД, работающая под управлением oracle enterprise edition, создает план, в котором используется индекс и объединяются результаты. Можно ли это сделать с помощью standard edition? »
Для завершения ответа: Enterprise Edition поддерживает методы индексации растровых изображений. Часто, когда у оптимизатора есть выбор между использованием нескольких индексов (или здесь одного и того же пространственного индекса для нескольких предикатов), он использует их оба.
Это делается путем получения результатов от каждого предиката (набора идентификаторов строк) и преобразования его в растровое изображение. Тогда просто объединить эти растровые изображения (здесь их упорядочивания) и извлечь результат обратно в список идентификаторов строк для получения фактических результатов.
Этого не существует в Standard Edition. Единственный вариант для оптимизатора — использовать его для индекса (для запроса, который объединяет несколько предикатов в условии AND ) или просто выполнить полное сканирование таблицы с помощью OR (поскольку условие OR делает условие запроса очень мало избирательным).
Замена условия OR ОБЪЕДИНЕНИЕМ ALL — это правильный подход: теперь у нас есть два запроса, которые оптимизируются независимо, и оба будут использовать пространственный индекс.
Ответ №3:
Хотя локатор доступен как в стандартной, так и в корпоративной версиях Oracle Database 11g, для некоторых функций локатора требуются функции базы данных, которые недоступны или ограничены в стандартной версии. Некоторые из этих функций локатора и их доступность перечислены в http://docs.oracle.com/cd/E11882_01/appdev.112/e11830/sdo_locator.htm#SPATL1276
Ваш исходный запрос может относиться к «Параллельным построениям пространственного индекса», который поддерживается только в Enterprise Edition.