С точки зрения производительности, разница намного сложнее, чем совет Tim Hall, который OMG Ponies связывает с . Я полагаю, что этот совет является введением в более крупный раздел, который был извлечен для сети - я ожидаю, что Тим продолжил делать большинство, если не все из этих пунктов в книге. Кроме того, все это обсуждение зависит от используемой вами версии Oracle. Я считаю, что это правильно для 10.2, 11.1 и 11.2, но есть определенные различия, если вы начнете возвращаться к более старым версиям.
Конкретный пример в подсказке, прежде всего, довольно нереалистичен. Я никогда не видел, чтобы кто-то кодировал однорядную выборку, используя явный курсор, а не SELECT INTO. Поэтому тот факт, что SELECT INTO более эффективен, имеет очень ограниченное практическое значение. Если мы обсуждаем циклы, то производительность, которая нас интересует, заключается в том, насколько дорого обходится получение множества строк. И вот тут начинается сложность.
Oracle представила возможность СОБЫТИЯ ОБЪЕМА ДАННЫХ из курсора в коллекцию PL / SQL в 10.1. Это гораздо более эффективный способ передачи данных из механизма SQL в коллекцию PL / SQL, поскольку он позволяет минимизировать сдвиги контекста, выбирая сразу несколько строк. И последующие операции с этими коллекциями более эффективны, потому что ваш код может оставаться в движке PL / SQL.
Чтобы максимально использовать синтаксис BULK COLLECT, вам, как правило, приходится использовать явные курсоры, потому что таким образом вы можете заполнить коллекцию PL / SQL, а затем использовать синтаксис FORALL для записи данных обратно в базу данных. (исходя из разумного предположения, что если вы выбираете кучу данных в курсоре, существует высокая вероятность того, что вы выполняете какие-то манипуляции и сохраняете манипулированные данные где-то). Если вы используете неявный курсор в цикле FOR, как правильно указывает OMG Ponies, Oracle выполнит BULK COLLECT за кулисами, чтобы сделать выборку данных менее дорогой. Но ваш код будет выполнять медленные построчные вставки и обновления, потому что данные не находятся в коллекции. Явные курсоры также предоставляют возможность явной установки LIMIT, что может повысить производительность по сравнению со значением по умолчанию 100 для неявного курсора в цикле FOR.
В общем, если вы используете версию 10.2 или выше и ваш код выбирает данные и записывает их обратно в базу данных,
быстрый
- Явные курсоры делают BULK COLLECT в локальную коллекцию (с соответствующим LIMIT) и используют FORALL для обратной записи в базу данных.
- Неявные курсоры выполняют БОЛЬШУЮ КОЛЛЕКЦИЮ для вас за кулисами вместе с однорядной записью обратно в базу данных.
- Явные курсоры, которые не выполняют BULK COLLECT и не используют преимущества коллекций PL / SQL.
Slowest
С другой стороны, использование неявных курсоров дает вам немало преимуществ от использования массовых операций за очень небольшие первоначальные затраты при рефакторинге старого кода или изучении новой функции. Если большая часть вашей разработки на PL / SQL выполняется разработчиками, основной язык которых является чем-то другим или которые не обязательно идут в ногу с новыми языковыми возможностями, циклы FOR будут легче понять и поддерживать, чем явный код курсора, который использовал все новая функциональность BULK COLLECT. И когда Oracle вводит новые оптимизации в будущем, гораздо более вероятно, что неявный код курсора получит выгоду автоматически, в то время как явный код может потребовать некоторой ручной доработки.
Конечно, к тому моменту, когда вы устраняете неполадки с производительностью до того момента, когда вы действительно заботитесь о том, насколько быстрыми могут быть различные варианты вашего зацикливающегося кода, вы часто приходите к тому, что вам захочется подумать о перемещении большей логики в чистый SQL и полностью исключая зацикливание кода.