Re[4]: Задачка
От: Softwarer http://softwarer.ru
Дата: 19.09.05 21:34
Оценка: 1 (1) +1
Здравствуйте, _Lexx, Вы писали:

Скажем так, насколько я в курсе, для решения подобных задач используется так называемый R-индекс. Я понаслышке знаком с этой областью; вкратце, это дерево переменной высоты, в котором каждый узел покрывает некую область пространства (отрезок в одномерном случае). То есть часть прямой, покрытая отрезками, делится на несколько меньших отрезков, те — на еще меньшие итп; соответственно, можно довольно быстро перейти от корня к отрезкам, "близким" определенной точке. Не знаю, как решается коллизия, если область нельзя разбить на меньшие так, чтобы не разрезать один из реальных отрезков. Проблема в том, что если мы говорим об SQL и не подразумеваем Oracle (где есть возможность создания собственных типов индексов, а r-индексы реализованы) то вряд ли удастся найти эффективное решение на основе имитации R-индекса.

Практически, полагаю, я бы просто сделал партиционированную таблицу (партиции по диапазонам значений левых границ отрезка, субпартиции по диапазонам значений правых границ). В этом случае обычный запрос с условием X between Left and Right эффективно отбросит партиции, в которых заведомо нет нужных отрезков. Эта возможность, насколько я знаю, доступна уже не только в Oracle.

Стандартное решение, о котором всегда следует помнить — выделение стандартных областей. Допустим, есть отрезок с координатами 1,1 ... 2,6. Мы можем сказать, что он пересекает стандартные отрезки [1..2] и [2..3]. Поэтому — вставим во вспомогательную таблицу записи

id, 1
id, 2

где id — идентификатор отрезка. Теперь, желая найти все отрезки, содержащие X, можно выполнить следующий запрос:

select
  p.id,
  p.left,
  p.right
from
  MainTable p,
  ServeTable s
where 
  s.value = trunc ( :x ) and
  s.id = p.id and
  :x between p.left and p.right


В этом случае довольно просто построить пример, где этот метод будет намного эффективнее простого поиска по одной таблице и столь же легко построить пример, где он будет намного менее эффективным.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.