Re: "Входная очередь" средствами Ораскла
- From
- Denis Zaitsev (2:5033/33.4)
- To
- Grigoriy Shpakov (2:5054/37.63)
- Date
- 2005-04-14T12:55:40Z
- Area
- RU.RDBMS.ORACLE
Приветствую тебя, Grigoriy!
В ответ на твое письмо от 14 Apr 05:
GS> Индекс используется. Но все равно получается неприемлемо медленно.
Значит или индекс в данном случае неэффективен (перестроить?)
или надо менять алгоритм.
DZ>> наверняка уже перекошен и нуждается в перестройке. Может вам его
DZ>> реверсивным сделать?
GS> А что это даст?
Ну, мне показалось что это позволит поддерживать более сбалансированный индекс,
хотя я забыл что он совершенно не подходит для сортировки (и вообще для диапазонного поиска), так что увы :(
GS> Определение количества строк - это лишний скан по таблице. А у нас
GS> время - очень критичный параметр.
Я вообще думал что кол-во строк будет определяться один раз на начало цикла обработки, select count(*) оракл дополнительно оптимизирует, так что много ресурсов этот запрос по идее не отнимет. Но если результат этого запроса поможет сократить время выполнения 20 000 операторов select min() .. то пуркуа бы и не па? :)
Хотя вы говорите что индекс все равно используется, а мой совет был направлен на то чтобы подсказать оптимизатору его использовать (в случае драматического увеличения кол-ва строк). Но раз использование индекса не дает явного прироста в производительности, я больше склоняюсь к изменению общего алгоритма просмотра очереди :)
DZ>> Ну и наконец, зачем в цикле каждый раз выполнять запрос если можно
DZ>> один раз сделать что-то вроде:
DZ>> for c in (select * from входная_очередь
GS> Затем, что:
GS> 1) Если "select *" скажет "not found", то этот цикл тут же
GS> останавливается. А нам надо, чтобы он ждал наступления события, которое
GS> нужно обработать;
Не скажет он "not found", просто не сделает ни одной итерации.
Ну сделайте бесконечный цикл вокруг это цикла (с проверкой флажка "стоп машины" ;), возможно со sleep'ом в конце, чтобы не молотить вхолостую (если обнаружилось что внутренний цикл не обработал ни одной строки, т.е очередь пуста). Как-то же вы делаете это сейчас, если select min() .. ничего не возвращает?
GS> 2) Непонятно, как ведет себя эта конструкция, если в процессе
GS> цикла по
GS> этому "select *" в таблицу-очередь будут вставлены новые записи.
Очень просто. Вы их не увидите - результат запроса (курсора) определен на
момент начала его выполнения, т.е. новые записи вы увидите только на следующей итерации обработки очереди.
А то может действительно глянуть в сторону AQ? Все же встроенный механизм должен работать пошустрее самописного (если даже опустить аспект "изобретения велосипеда"). Я вот смотрю, в 9-ке даже появились callback-функции, т.е. если появилась запись в очереди, дергается обработчик..
Искренне ваш.
--- GolDEAD+/W32 * Jagular Team *
* Origin: Fast, good, cheap: pick two.. (2:5033/33.4)
SEEN-BY: 452/25 461/33 74 106 640 464/34 465/204 469/125 550/5068 4623/56
SEEN-BY: 4625/9 4626/100 4641/444 4653/10 4657/50 5002/76 5002 5003/34 5004/58
SEEN-BY: 5010/53 5011/13 5015/4 28 5020/20 52 104 115 128 150 175 401 600 642
SEEN-BY: 5020/794 921 968 982 1100 1169 1212 1234 1356 1626 1642 1873 1930
SEEN-BY: 5020/2200 4400 4441 5021/3 44 5023/11 5025/19 151 5026/78 5030/69 195
SEEN-BY: 5030/382 920 1016 5032/11 16 5033/1 4 14 16 21 26 33 35 36 5034/8
SEEN-BY: 5035/10 5036/13 5037/21 5040/33 47 5041/4 5045/7 42 5049/157 5050/9
SEEN-BY: 5050/41 5051/35 5053/16 5054/1 8 9 28 35 37 45 50 5056/16 5058/77
SEEN-BY: 5059/20 5060/90 5063/5 41 51 5064/7 35 36 5070/26 66 5071/22 5079/49
SEEN-BY: 5082/6 5083/13 5090/23 5093/27 5100/113
PATH: 5033/33 1 5020/52 5054/1 37