Форум: "Прочее";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];
ВнизВозникла необходимость ознакомиться с Oracle Найти похожие ветки
← →
evvcom © (2006-06-07 11:33) [40]
> Игорь Шевченко © (06.06.06 13:36) [1]
> Ширше
"Ширше" не правильно, правильно "ширее" :-)
> Petr V. Abramov © (06.06.06 13:43) [5]
> >1.
> на компе фломастером необходимо написать "СЕРВЕР" :)
> если есть свободных ~256М опреативки - можно.
У меня дома всего 256, не шустро, но крутится. Службу стартую только по необходимости естественно. :-)
← →
Desdechado © (2006-06-07 11:49) [41]Курдль © (07.06.06 10:12) [37]
> Оракл - единственный полноценный версионник.
Был бы он версионником, не болел бы этой странной, тщательно культивируемой и всеми "любимой" болезнью по имени "ORA-04091 Table is mutating, trigger/function may not see it".
PS холивара не будет
← →
evvcom © (2006-06-07 11:54) [42]
> Desdechado © (06.06.06 21:52) [26]
> Но следует помнить, что IB - версионник, а Оракл и MS - блокировочники.
Oracle блокировщик? Оп. Это что-то новое. Блокируются только изменяемые в данный момент (до коммита или ролбэка) записи, но это и правильно.
> Sergey Masloff (06.06.06 22:26) [31]
> Desdechado © (06.06.06 22:23) [29]
> >Я про девятку R2 говорил, хотя забыл указать.
> А ну это известное дело. Она у меня вообще просто не заработала
> на 500 мегах оперативки.
А что такое R2? Я чего-то не знаю, видимо. У меня 9i дома на 256М нормально запускается. Из служб стартую только Listener и базу. Память надо смотреть, так не знаю. А на винте, что поставишь. Можно и скрипты не ставить, и тестовые (учебные) базы, тогда может и на 9i много не съестся?
← →
evvcom © (2006-06-07 11:59) [43]
> Desdechado © (07.06.06 11:49) [41]
> Курдль © (07.06.06 10:12) [37]
> > Оракл - единственный полноценный версионник.
> Был бы он версионником, не болел бы этой странной, тщательно
> культивируемой и всеми "любимой" болезнью по имени "ORA-
> 04091 Table is mutating, trigger/function may not see it".
Эта ошибка не из-за блокировок. Ты путаешь. Не используй селектов (DML) в триггерах on each row, которых в MSSQL нет (или может уже появились?, не знаю про IB), применительно к изменяемым таблицам, и не получишь такой ошибки.
← →
Курдль © (2006-06-07 12:13) [44]
> Desdechado © (07.06.06 11:49) [41]
> "ORA-04091 Table is mutating, trigger/function may not see it".
Это не болезнь и не ошибка. Даже не фитча. Это предупреждение нерадивому программисту, прямо вытекающая из версионности, что "нефиг рубить сук, на котором сидишь".
Если среда разработки предупреждает тебя о зацикливании программы, бесконечной рекурсии, или переполнении стека, это ошибка? :)
← →
evvcom © (2006-06-07 12:22) [45]
> Это не болезнь и не ошибка.
Нет, это все-таки и болезнь, и ошибка. Только не Оракла. :-)
← →
evvcom © (2006-06-07 12:25) [46]
> прямо вытекающая из версионности
Кстати, с версионностью, по-моему, совсем никак не вяжется, хотя бы потому, что возникает в той же самой сессии. А из другой сессии будет совсем другая ошибка (опять же не разработчика)
← →
Petr V. Abramov © (2006-06-07 12:53) [47]> evvcom © (07.06.06 11:33) [40]
можно и в меньше запихать. только у автора ветки с первого раза может не получиться.
← →
Desdechado © (2006-06-07 12:59) [48]evvcom © (07.06.06 11:54) [42]
> Oracle блокировщик? Оп. Это что-то новое. Блокируются только изменяемые
> в данный момент (до коммита или ролбэка) записи, но это и правильно.
Блокируются? Значит, блокировочник.
Версионник IB просто создает копию записи для тебя, и терзай ее как хочешь независимо от других. Помни также, что при использовании некоторых видов индексов (например, BITMAP) блокируются и другие записи, которые ты не трогаешь (если изменяется индексное поле).
> А что такое R2?
Это Release 2 (9.2 или 10.2)
> Эта ошибка не из-за блокировок. триггерах on each row (не знаю про IB)
в IB все триггеры одинаковые, для каждой записи.
И у него нет проблем с чтением изменяемой таблицы, т.к. он читает версии записей, относящиеся к текущей транзакции. А у Оракла проблема есть, т.к. нет понятия версии. Он не понимает, какие данные взять.
← →
Petr V. Abramov © (2006-06-07 13:03) [49]> Это предупреждение нерадивому программисту, прямо вытекающая из версионности
из версионности это никак не вытекает. Вытекает из того, что если DML затрагивает несколько записей, и при этом в row-триггере делать селект, он вернет полную белиберду - половина записей в виде ДО DML-statement`а, половина - после. Еще противоречит принципу, что на конкретный SCN мы всегда увидим одни и те же данные.
← →
Petr V. Abramov © (2006-06-07 13:04) [50]> Desdechado © (07.06.06 12:59) [48]
> А у Оракла проблема есть, т.к. нет понятия версии. Он не понимает, какие данные взять.
Как это нету??? А SCN?
← →
evvcom © (2006-06-07 13:11) [51]
> Версионник IB просто создает копию записи для тебя, и терзай
> ее как хочешь независимо от других.
IB не знаю, спорить не буду, только спрошу. Хорошо. Одна сессия изменила запись без коммита, другая аналогично. Потом 2 коммита. Что получим? И это правильно?
> в IB все триггеры одинаковые, для каждой записи.
> И у него нет проблем с чтением изменяемой таблицы
Я делаю вывод, что в IB нет понятия изменяемой таблицы. Есть понятие измененной таблицы. В Оракле присутствуют оба эти понятия, и они различны. Ты просто не разобрался с этим.
> > А что такое R2?
> Это Release 2 (9.2 или 10.2)
А... Ну тогда у меня R2 с 6 патчем.
← →
Petr V. Abramov © (2006-06-07 13:16) [52]> evvcom © (07.06.06 13:11) [51]
> IB не знаю, спорить не буду, только спрошу. Хорошо. Одна сессия изменила запись без коммита, другая аналогично.
Ну IB тоже не дураки писали. Вторая транзакция подождет коммита первой. "Кто первый встал, того и тапки"
← →
evvcom © (2006-06-07 13:25) [53]
> Ну IB тоже не дураки писали
Ну я и не говорил, что дураки. Мне просто было интересно, как они разрулили тогда такую ситуацию?
> Вторая транзакция подождет коммита первой. "Кто первый встал,
> того и тапки"
Ну, если одна из них делает ролбэк, вопросов нет, а если коммит, вторая тогда что, ошибку выплюнет? В [41] помнится списали ошибку, возникающую из недопонимания программиста, на отсутствие версионности. Здесь аналогичная ситуация.
← →
pavel_guzhanov © (2006-06-07 13:34) [54]Спасибо за ответы и за советы. Завтра поеду на Горбушку, надеюсь, что там найду дистрибутив... и начну дома изгаляться... над собой больше всего :0)))
← →
kaif © (2006-06-07 13:50) [55]В ORACLE есть одно хорошее примущество. Возможность делать SELECT над SELECT. Это очень удобно даже просто при разработке. Например, хочешь узнать, сколько записей тебе вернет некий запрос. Можно вполне написать такую вещь:
SELECT COUNT(*) FROM (SELECT ... FROM ... WHERE ...).
Любопытно, что возможны не просто SELECT анд SELECT-ом, но и объединение результатов нескольких запросов в запросе более высокого уровня через алиасы запросов.
Что-то вроде этого:
SELECT
A.ID, A.NAME, B.S_AMOUNT
FROM
T1 A,
(SELECT ID, SUM(AMOUNT) S_AMOUNT
FOM T2 WHERE ... GROUP BY ID ORDER BY ID) B
WHERE
A.ID = B.ID
причем конструкцию ORDER BY можно применять и во вложенном запросе. Это позволяет как бы проиндексировать внутренний набор перед объединением (я такое делал) и значительно ускорить результат.
Правда при работе с ORACLE я столкнулся с одной очень странной вещью: оптимизатор в определенной ситуации может превратить некоррелированный запрос в коррелированный (при случайном лишнем условии во внутреннем запросе). Вообще оптимизатор ORACLE меня несколько раз смутил непредсказуемостью своих решений.
А вообще, конечно, классный сервер. Жаль только дорогой шибко.
← →
Sergey13 © (2006-06-07 13:53) [56]2[55] kaif © (07.06.06 13:50)
> Вообще оптимизатор ORACLE меня несколько раз смутил непредсказуемостью своих решений.
Который из оптимизаторов?
← →
Desdechado © (2006-06-07 13:53) [57]Petr V. Abramov ©
evvcom ©
я, возможно, чего-то еще не понимаю или не знаю
но даже при наличии версионности (сколько, кстати, возможно таких версий у записи?) она явно какая-то не такая, как в IB
может, просто под одним словом понимаются разные вещи?
← →
evvcom © (2006-06-07 13:59) [58]
> SELECT COUNT(*) FROM (SELECT ... FROM ... WHERE ...).
Ну вообще такое умеет, наверное, любой современный сервер.
> SELECT
> A.ID, A.NAME, B.S_AMOUNT
> FROM
> T1 A,
> (SELECT ID, SUM(AMOUNT) S_AMOUNT
> FOM T2 WHERE ... GROUP BY ID ORDER BY ID) B
> WHERE
> A.ID = B.ID
А это разновидность записи join, тоже, наверное, есть в любом сервере. Даже в Local SQL есть (я не говорю про вложенный select)
> Вообще оптимизатор ORACLE меня несколько раз смутил непредсказуемостью
> своих решений.
Это от непонимания или от недопонимания. Но иногда у Оракла действительно крышу сносит. Но переделав немного запрос, заставляешь его проглотить и такое.
← →
Desdechado © (2006-06-07 14:01) [59]> оптимизатор ORACLE меня несколько раз смутил непредсказуемостью своих решений
там у него настроек - вагон и маленькая тележка
все предсказуемо, только вот способ предсказания является нетривиальной формулой от настроек + загрузки + порядка соединения таблиц + количества и разнообразия данных в таблицах + актуальности статистики индексов + ...
← →
ораклоид (2006-06-07 14:03) [60]>>kaif © (07.06.06 13:50) [55]
>>В ORACLE есть одно хорошее примущество. Возможность делать SELECT над SELECT.
Я тебе страшную вещь скажу: такое умеет делать даже тупой Access.
← →
kaif © (2006-06-07 14:04) [61]Sergey13 © (07.06.06 13:53) [56]
2[55] kaif © (07.06.06 13:50)
> Вообще оптимизатор ORACLE меня несколько раз смутил непредсказуемостью своих решений.
Который из оптимизаторов?
На знаю. Их много? Я работал с ORACLE 9i.
Не настолько долго, чтобы серьезно разбираться с оптимизаторами. Но запросы у меня были многоэтажные (с генерируемым текстом). По умолчанию что используется? Насколько я понял тогда: "экономический принцип оптимизации" (или что-то в этом роде, не помню - по английски читал в описании).
Но у меня была ситуация, над которой мы с товарищем ломали весь день голову. Именно та, о которой я сказал: безобидный некоррелированный запрос ORACLE исполнял как коррелированный. То есть многократно вызывал подзапрос, хотя результат при каждом вызове должен был быть заведомо одинаков (в условиях подзапроса никак не использовались поля из внешнего запроса). Только когда мы приблизительно поняли, как ORACLE пытается рассуждать, мы выбросили одно лишнее (тривиальное) условие из подзапроса и все заработало верно. Лишнее условие возникало из-за того, что тексты генерировались автоматически и в определенной ситуации два разных условия могли друг друга логически дублировать - поначалу я не видел в этом криминала.
← →
Danilka © (2006-06-07 14:06) [62][55] kaif © (07.06.06 13:50)
OracleXE бесплатный. Но с некоторыми ограничениями, несущественными для малых БД.
А там, где базы большие, обльше ограничений, уже стоимость сервера будет несущественной.
:)
← →
kaif © (2006-06-07 14:09) [63]ораклоид (07.06.06 14:03) [60]
>>kaif © (07.06.06 13:50) [55]
>>В ORACLE есть одно хорошее примущество. Возможность делать SELECT над SELECT.
Я тебе страшную вещь скажу: такое умеет делать даже тупой Access.
Очень сомневаюсь, что Access в своем синтаксисе поддерживает алиасы для подзапросов. Если даже это так, то сколько уровней вложенности подзапросов позволяет следать Access ?
И какова при этом скорость?
А может ли Access принять конструкцию ORDER BY в подзапросе?
Я сравниваю с IB. В нем, к сожалению, запрос над запросом сделать невозможно, хотя можно выкрутиться через хранимую процедуру с SUSPEND. Я знаю, что MS SQL может тоже делать запрос над запросом, нот я лично такие вещи в MS SQL не делал.
Просто в ORACLE это сделано великолепно.
Я лишь это хотел сказать.
← →
Petr V. Abramov © (2006-06-07 14:10) [64]логику оптимайзера можно понять, сказав
alter session set events "10053 trace name context forever, level 1"
и зимним вечером почитав trace-файл.
← →
evvcom © (2006-06-07 14:11) [65]
> но даже при наличии версионности (сколько, кстати, возможно
> таких версий у записи?) она явно какая-то не такая, как
> в IB
> может, просто под одним словом понимаются разные вещи?
Вообще в оракле блокировка наступает только (я сейчас не говорю про пользовательские блокировки) при попытке во второй сессии изменить уже изменяемую запись. Но если запись селектится, никаких блокировок не наступает. Даже если за время (точно не помню правильное название) неизменности данных во время транзакции (первая сессия) происходит изменение этих данных в другой сессии, первая продолжает работать со своей старой версией. Оракл эту инфу добывает из журнала изменений что ли. Но это уже из темы "Уровни изолированности транзакций".
За некоторые "термины" прошу не пинать, не админ я. :)
← →
Sergey13 © (2006-06-07 14:12) [66]2[61] kaif © (07.06.06 14:04)
> Их много?
Их 2. По стоимости и по правилам. По умолчанию работает первый. Но для его работы должна регулярно собираться статистика. При отсутствии статистики работает второй. При нерегулярно собираемой статистике результаты могут быть непредсказуемы. Плюс параметры настройки конечно.
← →
Petr V. Abramov © (2006-06-07 14:13) [67]> evvcom © (07.06.06 14:11) [65]
> Оракл эту инфу добывает из журнала изменений что ли.
из undo tablespace, до 9-ки - сегмента отката.
а журнализирутся все - и данные, и undo
← →
Petr V. Abramov © (2006-06-07 14:14) [68]> Их 2. По стоимости и по правилам.
по деньгам и по понятиям :)
← →
kaif © (2006-06-07 14:20) [69]2 Sergey13 ©
Логика той ошибки была именно в применении оптимизации по стоимости (вспомнил термин :). Однако стоимость он оценивал достаточно по-идиотски. Таблицы подзапроса были маленькие, а внешнего - большие. Вот он и прикинул, что ему лучше выполнить подзапрос много раз. Хотя поздапрос возвращал заведомо всегда один и тот же результат и ORACLE имел достаточно информации, чтобы до этого додуматься.
Я бы тогда не возмутился, если бы в документации не было черным по белому написано, что такие запросы всегда рассматриваются как некоррелированные (если в подзапросе не используются значения полей из таблиц внешнего запроса). В результате у нас запрос работал 20 минут вместо 1 секунды. Пока мы не выбросили лишнее условие.
← →
Sergey13 © (2006-06-07 14:23) [70]2[69] kaif © (07.06.06 14:20)
>Однако стоимость он оценивал достаточно по-идиотски.
Какая статистика, такая и оценка. 8-)
Вполне вероятно, что, когда-то в прошлом году однажды собранная, статистика говорила СВО, что выгоднее делать именно так.
← →
ораклоид (2006-06-07 14:47) [71]>>kaif © (07.06.06 14:09) [63]
>>Очень сомневаюсь, что Access в своем синтаксисе поддерживает алиасы >>для подзапросов.
А не надо сомневаться, можно проверить. Ответ - поддерживает.
>>Если даже это так, то сколько уровней вложенности подзапросов >>позволяет следать Access ?
Проверил 10, дальше надоело.
>>А может ли Access принять конструкцию ORDER BY в подзапросе?
Может. А зачем? А в Oracle зачем?
>>Просто в ORACLE это сделано великолепно.
Да и многое другое сделано с умом, лично мне приятно иметь дело с этим (9.2) продуктом :-)
← →
evvcom © (2006-06-07 15:09) [72]
> >>А может ли Access принять конструкцию ORDER BY в подзапросе?
> Может. А зачем? А в Oracle зачем?
Я с этим столкнулся пока только однажды. Написал древовидный select с order by siblings, потом добавил rownum, потом всё это надо было просеять и отсортировать обрезанное дерево by siblings. Ну а самый внешний select был естественно уже не древовидный, вот и сортировал во второй раз по выбранному ранее rownum.
← →
Desdechado © (2006-06-07 16:21) [73]evvcom © (07.06.06 13:11) [51]
> Я делаю вывод, что в IB нет понятия изменяемой таблицы.
> Есть понятие измененной таблицы. В Оракле присутствуют оба эти понятия,
> и они различны. Ты просто не разобрался с этим.
Я не понимаю, что значит "изменяемая таблица". Для данных, имхо, достаточно двух состояний - до изменения и после. Зачем нужно состояние "в процессе", если все равно к ним в это время не обратиться (мутации, етить!)? Толк какой от него? Примерчик приведешь?
Я делаю вывод, что "в процессе" - это и есть та самая блокировка.
← →
atruhin © (2006-06-07 16:26) [74]
> Я сравниваю с IB. В нем, к сожалению, запрос над запросом
> сделать невозможно
в двойке можно
← →
jack128 © (2006-06-07 17:14) [75]evvcom © (07.06.06 13:11) [51]
Что получим?
зависит от параметров транзакций. Либо исключение еще при запросе получим, либо при коммите второй транзакции..
← →
evvcom © (2006-06-07 18:03) [76]
> Я не понимаю, что значит "изменяемая таблица".
В оракле существуют 2 вида триггеров: триггеры уровня оператора и уровня строки (on each row), каждый из них соответственно делится еще на 2 вида (подвида, кому как угодно): до изменения и после изменения. Естественно каждый из них может действовать при insert, update, delete и в комбинации. Допустим требуется выполнить update таблицы с условием where <условие>, под которое попадает несколько строк. Алгоритм:
1. Выполняется before уровня оператора.
2. Начинается скан таблицы (индекса), находится первая строка, удовлетворяющая условию.
3. Выполняется before уровня строки.
4. Вносятся изменения.
5. Устанавливается флаг изменяемой таблицы.
6. Выполняется after уровня строки.
7. Ищется следующая строка, удовлетворяющая условию.
8. Если нашлась, то переход к шагу 3.
9. Иначе сбрасывается флаг изменяемой таблицы.
10. Выполняется after уровня оператора.
Если на каком-то из шагов произошла ошибка, то весь update на фиг. Вроде ниче не забыл.
> Для данных, имхо, достаточно двух состояний - до изменения и после.
> Зачем нужно состояние "в процессе", если все равно к ним
> в это время не обратиться (мутации, етить!)? Толк какой
> от него? Примерчик приведешь?
Нужно не состояние в процессе, а нужно бывает обработать текущие значения строки. Например, в MSSQL формируются таблицы inserted и deleted. Если надо проанализировать правильность update-а записи, надо ее найти в обеих таблицах, и потом только сравнивать. Поскольку записей там может быть много и различных условий сравнения тоже, мы использовали курсоры. Если надо что-то поправить приходилось делать опять update (чего, уже не помню, то ли целевой таблицы, то ли таблицы inserted, давно уже не работал с MSSQL, кто знает, меня поправят).
В Oracle создаешь триггер уровня строки (before), выполняешь проверку и если надо что-то подправить, пишешь, например так::new.fld := :old.fld + 1
+ все это делается в одном и том же скане.
> Я делаю вывод, что "в процессе" - это и есть та самая блокировка.
Нет, это не блокировка. Просто после изменения первой строки группы выставляется флаг, а после того как вся группа строк изменена флаг сбрасывается. И если select происходит из таблицы с установленным флагом, то и получаешь ту самую ошибку про "мутацию".
Все побег домой, если что, остальное завтра...
← →
Desdechado © (2006-06-07 18:48) [77]evvcom © (07.06.06 18:03) [76]
Про триггеры и шаги выполнения - факты известные и простые.
Но смысл состояния "в процессе" они не раскрывают. Ибо шаги 2 и 7 не формализованы, следовательно, можно считать, что порядок изменения записей произвольный или (что то же самое) одновременный.
Таким образом, флаг этот нужен только самому Ораклу для разгребания своих проблем, а не для пользователя/разработчика программ.
Блокировка в этом случае получается даже не для других транзакций, а и для текущей тоже.
Т.е. приходим к заключению, что это блокировка, о которой я говорил.
И фраза "это не блокировка. Просто после изменения первой строки группы выставляется флаг" дает всего лишь определение блокировки другими словами, оставляя неизменным смысл.
← →
ораклоид (2006-06-07 20:15) [78]Desdechado © (07.06.06 18:48) [77]
ОК. Допустим есть таблица TABLE_1 из 5-ти строк. Есть запрос типаupdate TABLE_1 set id = id + 1
Есть триггерbefore update on TABLE_1 for each row
, срабатывающий, естесственно, для каждой изменяемой строки. В теле этого триггера есть запросselect t.id bulk collect into AnyCollection from TABLE_1 t
.
Триггер выполняется третий раз. Вопрос, какие зн-я должны попасть в AnyCollection?
После ответа на него уйдут все вопросы про «…разгребания Oracle своих проблем…».
← →
Desdechado © (2006-06-07 20:52) [79]ораклоид (07.06.06 20:15) [78]
Для такой ситуации важен порядок изменения записей, который можно явно определить в этом третьем срабатывании. А т.к. порядок неизвестный, то указанный в триггере запрос - бессмысленный.
Но если ответить более конкретно, то попасть должны значения из измененных записей новые, а из нетронутых - старые, поскольку для некоторых строк триггер уже сработал, а для некоторых - нет. Для текущей срабатываемой записи - старое, т.к. триггер BEFORE.
> После ответа на него уйдут все вопросы
Ответил. Не ушли....
← →
Petr V. Abramov © (2006-06-07 23:59) [80]Desdechado © (07.06.06 16:21) [73]
> Я делаю вывод, что "в процессе" - это и есть та самая блокировка.
" процессе" - это бред сивой кобылы, никому не нужный. т.к. порядок изменения произвольный. так что "блокирУй, не блокирУй, все равно получишь" ... ora-XXXX :)
и что за "флаг", который Вы обсуждаете???
а для анализа НАБОРА изменяемых записей ДО и ПОСЛЕ DML есть BEFORE и AFTER STATEMENT-LEVEL триггеры.
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2006.07.09;
Скачать: [xml.tar.bz2];
Память: 0.65 MB
Время: 0.014 c