2013-07-18 3 views
1

У меня есть таблица challenge, содержащая около 12000 строк. Каждая точка соединяется с четырьмя точками вокруг него, например 100 подключается к 99 101 11 и 189. Я пробовал это с помощью таблицы с небольшим масштабом, и он работал нормально, но по мере увеличения размера таблицы запрос стал экспоненциально медленнее и теперь он даже не закончит. Вот мой запросЧрезвычайно медленный запрос с использованием CONNECT BY Oracle 10

SELECT level, origin, destination 
FROM challenge 
WHERE destination = 2500 
START WITH origin = 1 
CONNECT BY NOCYCLE PRIOR destination = origin; 

Любые советы по оптимизации этого запроса будут очень признательны.

+0

Добавить отсутствующие индексы в 'destination'? – dasblinkenlight

+0

** Вам нужно показать нам определения таблиц и индексов. ** Для диагностики медленных запросов требуются полные определения таблиц и индексов, а не просто описание или парафраз. Возможно, ваши таблицы плохо определены. Возможно, индексы создаются неправильно. Возможно, у вас нет указателя на тот столбец, который, как вы думали, вы делали. Не видя определения таблиц и индексов, мы не можем сказать. Если вы знаете, как сделать «EXPLAIN» или получить план выполнения, поместите результаты в вопрос. –

ответ

0

Итак, вы находите каждый путь от узла 1 до узла 2500 в графе степени 4 (прямоугольная решетка?) Тысяч узлов. Я ожидаю, что их будет довольно много. Задача просто попросила вас посчитать их? Потому что я думаю, что дело в том, что вам нужно выяснить, сколько есть, делая математику, а не вычисление грубой силы.

Например, если это прямоугольная сетка 50x50 с узлом 1 и узлом 2500 в противоположных углах, то минимальная длина пути составляет 100 шагов. Путь из 100 шагов будет иметь 50 из них по горизонтали и 50 из них по вертикали, и они могут быть в любом порядке. Объясните, сколько способов вы можете упорядочить строку из 50 H и 50 V, и вы можете обнаружить, что это число, с которым даже могучий Oracle будет иметь проблемы. (Генерация строк, то есть. Выполнение вычисления просто требует большой целочисленной арифметики, которую Oracle, возможно, сделает довольно быстро, как только вы сообщите ей формулу.)

И ваш запрос на самом деле хуже этого. Он не запрашивает только пути минимальной длины. Таким образом, он также вернет все пути длины 102, которые удалятся от места назначения где-то на этом пути. И пути длиной 104, которые занимают 2 обратных шага. И пути длиной 2498, которые посещают почти все узлы! Подсчет этих путей сложнее, чем подсчет коротких путей, потому что вы должны исключать те, которые пересекают себя.

+0

Да, Wumpus, вы правы. Это очень большой сетчатый шаблон или тысячи узлов, каждый из которых может подключаться к ним непосредственно вокруг него. Проблема с использованием математики заключается в том, что существует множество конкретных узлов, которые только соединяются на определенных сторонах, поэтому я пытаюсь использовать запрос. Я хотел бы, чтобы он возвращал начало, место назначения и уровень для кратчайшего пути. Мои определения для таблицы: create table challenge (origin int, destination int); создать индекс challenge_origin на вызов (происхождение); создать вызов общественного синонима для вызова; –

+0

Решатель лабиринта! В SQL! Конечно, тогда «используйте неправильный инструмент для задания, чтобы показать свое творчество». В любом случае проблема с вашим запросом заключается в том, что он находит ** все ** пути. Добавление 'и rownum = 1' остановит его, когда оно найдет первое, но оно не будет гарантировано самым коротким. Для этого вам нужен поиск по ширине, а CONNECT BY - в первую очередь. Поиск «в ширину» в документации оракула дает следующее: http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm –