Что такое система координат ваших данных? И, самое главное, что допуск вы установили в свои метаданные?
Некоторые другие комментарии:
1) Не используйте связаны с буферным подходом. Просто используйте подход на расстоянии.
2) Вам не нужно PL/SQL цикл для такого рода запроса просто использовать простой CTAS:
create table orahancrosses as
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2
from orahan c1, orahan c2
where sdo_wihin_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE'
and c2.mi_prinx <> c1.mi_prinx;
3) Как написано, пары точек А и В, которые находятся в пределах 2 см будет возвращен дважды: один раз (A, B) и еще раз (B, A). Чтобы избежать этого (и возвращать только один из случаев), а затем написать запрос следующим образом:
create table orahancrosses as
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2
from orahan c1, orahan c2
where sdo_wihin_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE'
and c1.rowid < c2.rowid;
3) обработка количество точек вы упоминаете (400000+) должен работать лучше, используя технику SDO_JOIN, как это :
create table orahancrosses as
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2
from table (
sdo_join (
'ORAHAN','GEOLOC',
'ORAHAN','GEOLOC',
'DISTANCE=2 UNIT=CM'
)
) j,
orahan c1,
orahan c2
where j.rowid1 < j.rowid2
and c1.rowid = j.rowid1
and c2.rowid = j.rowid2;
Это, вероятно, все еще требует времени для обработки - в зависимости от емкости вашего сервера базы данных. Если вы являетесь лицензией для Oracle Enterprise Edition, и ваше оборудование имеет соответствующую емкость (количество ядер), то параллелизм может сократить прошедшее время.
4) Вы говорите, что используете Oracle 11g. Какая точная версия? Версия 11.2.0.4 является терминальной версией для 11gR2. Все, что старше, больше не поддерживается. К настоящему времени вы действительно должны быть на 12cR1 (12.1.0.2). Основное преимущество 12.1.0.2 в вашем случае - функция ускорения Vector Performance Accelerator, которая ускоряет работу ряда пространственных функций и операторов (только если вы владеете надлежащими лицензиями Oracle Spatial - она недоступна со свободной функцией Oracle Locator).
======================================
Используя две точки в вашем примере. Давайте вычислить расстояние:
select sdo_geom.sdo_distance(
sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),
sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null),
0.005
) distance
from dual;
DISTANCE
----------
.01000197
1 row selected.
Уведомление: Я не указываю никаких SRID. Предполагая, что координаты выражены в метрах, расстояние между ними действительно немного больше 1 см.
======================================
Причина, почему ваш Исходный синтаксис не работает, как вы заметили, из-за толерантности, который вы указываете для вызова SDO_BUFFER(). Вы передаете его как 0,5 (= 50 см) для получения буфера с радиусом 0,02 (2 см). Эффект заключается в том, что полученный буфер эффективно растворяется в самой точке.
Например, на толерантность 0,5:
select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.5) from dual;
Производит:
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(521554.782, 4230983.08, NULL), NULL, NULL)
В толерантностью 0.005:
select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005) from dual;
Вы получаете правильный буфер:
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 2), SDO_ORDINATE_ARRAY(521554.782, 4230983.06, 521554.802, 4230983.08, 521554.782, 4230983.1, 521554.762, 4230983.08, 521554.782, 4230983.06))
И очень близко точка теперь соответствует с этим буфером:
select sdo_geom.relate(
sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005),
'determine',
sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null),
0.005
) relation
from dual;
RELATION
-------------------------
CONTAINS
1 row selected.
============================= =========
Теперь тот факт, что ваши данные не имеют надлежащего явного SRID, означает, что использование явных единиц измерения или дистанционных поисковых запросов не будет работать. Поскольку база данных не знает, в какой системе координат находятся ваши данные, она не знает, как определить, что две точки меньше заданного числа см или м друг от друга. Все, что вы можете сделать, это предположить, что координаты находятся в метрах.
Таким образом, в примерах, которые я даю выше, заменить 'DISTANCE=2 UNIT=CM'
с 'DISTANCE=0.02'
Я работаю компания, которая использует оракул 11gR2 в некоторых проектах. Орахан имеет около 400 000 записей (строк). Я отредактирую asap мой вопрос и добавлю значение допуска в метаданные. –
Если компания использует 11gR2 и имеет системный администратор и администратор базы данных, то они, вероятно, уже находятся на 11.2.0.4. Тем не менее, в этой версии и с объемом данных, которые вам нужно обработать, подход SDO_JOIN определенно подходит для меня (я добавил синтаксис в свой ответ). В 12c будет отличаться функцией Vector Performance Accelerator. –
Я стараюсь, чтобы вы сказали, SDO_JOIN метод, и это очень быстро. Он выполнил эту работу за 2 минуты. Спасибо за это. Но проблема все еще остается. Он не находит пересечения, а некоторые точки имеют расстояние 1 см друг от друга. Я думаю, что diminfo моей колонки неверна. –