Как уже было сказано, база данных оптимизирована для операций над множествами. Буквально инженеры сидели и отлаживали / настраивали эту базу данных в течение длительных периодов времени. Шансы на их оптимизацию довольно малы. Существуют всевозможные забавные приемы, с которыми вы можете поиграть, если у вас есть набор данных для работы, например, пакетное чтение / запись диска, кэширование, многопоточность. Кроме того, некоторые операции сопряжены с высокими накладными расходами, но если вы делаете это одновременно с кучей данных, цена за единицу данных будет низкой. Если вы работаете только по одной строке за раз, многие из этих методов и операций просто не могут быть выполнены.
Например, просто посмотрите, как объединяется база данных. Изучив планы объяснения, вы увидите несколько способов выполнения объединений. Скорее всего, с курсором вы идете строка за строкой в одной таблице, а затем выбираете нужные значения из другой таблицы. По сути, это как вложенный цикл, только без цикла (который, скорее всего, скомпилирован в машинный язык и супер оптимизирован). SQL Server сам по себе имеет множество способов объединения. Если строки отсортированы, он будет использовать некоторый тип алгоритма слияния, если одна таблица мала, он может превратить одну таблицу в таблицу поиска хешей и выполнить объединение, выполнив O (1) поиск из одной таблицы в таблицу поиска. Существует множество стратегий объединения, которые есть во многих СУБД, которые помогут вам при поиске значений из одной таблицы в курсоре.
Просто посмотрите на пример создания таблицы поиска хешей. Для построения таблицы, вероятно, нужно выполнить m операций, если вы объединяете две таблицы, одна из которых имеет длину n, а другая - длину m, где m - это меньшая таблица. Каждый поиск должен иметь постоянное время, то есть n операций. Таким образом, в основном эффективность хеш-соединения составляет около m (настройка) + n (поиск). Если вы делаете это самостоятельно и не предполагаете поисков / индексов, то для каждой из n строк вам придется искать m записей (в среднем это равняется m / 2 поискам). Таким образом, в основном уровень операций изменяется от m + n (соединяя сразу несколько записей) до m * n / 2 (поиск по курсору). Также операции являются упрощениями. В зависимости от типа курсора выборка каждой строки курсора может быть такой же, как выбор другого из первой таблицы.
Замки тоже убивают тебя. Если у вас есть курсоры в таблице, вы блокируете строки (на SQL-сервере это менее серьезно для статических и forward_only курсоров ... но большая часть кода курсора, который я вижу, просто открывает курсор без указания какой-либо из этих опций). Если вы выполняете операцию в наборе, строки все равно будут заблокированы, но на меньшее количество времени. Также оптимизатор может видеть, что вы делаете, и он может решить, что более эффективно блокировать всю таблицу, а не набор строк или страниц. Но если вы идете строка за строкой, оптимизатор понятия не имеет.
Другое дело, что я слышал, что в случае с Oracle супероптимизирован для выполнения операций с курсорами, поэтому он не может сравниться с таким же штрафом за операции на основе множеств по сравнению с курсорами в Oracle, как в SQL Server. Я не эксперт Oracle, поэтому не могу сказать наверняка. Но несколько человек из Oracle говорили мне, что курсоры в Oracle более эффективны. Поэтому, если вы пожертвовали своим первенцем ради Oracle, вам, возможно, не придется беспокоиться о курсорах, обратитесь к местному высокооплачиваемому администратору базы данных Oracle:)