Почему люди ненавидят курсоры SQL так? [закрытый]

Исключение нулевого указателя генерируется, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  1. Вызов метода экземпляра объекта null.
  2. Доступ или изменение поля объекта null.
  3. Принимая длину null, как если бы это был массив.
  4. Доступ или изменение слотов null, как если бы это был массив.
  5. Бросок null как будто это было значение Throwable.

Приложения должны бросать экземпляры этого класса, чтобы указать на другие незаконные использования объекта null.

Ссылка: http://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

127
задан 7 revs, 3 users 64% 23 May 2017 в 12:17
поделиться

14 ответов

"Издержки" с курсорами являются просто частью API. Курсоры - то, как части RDBMS работают под капотом. Часто CREATE TABLE и INSERT имеют SELECT операторы, и реализация является очевидной внутренней реализацией курсора.

Используя высокоуровневые "основанные на наборе операторы" связывает результаты курсора в единственный набор результатов, означая меньше API назад и вперед.

Курсоры предшествуют современным языкам, которые обеспечивают первоклассные наборы. Старый C, КОБОЛ, Фортран, и т.д., должен был обработать строки по одному, потому что не было никакого понятия "набора", который мог использоваться широко. Java, C#, Python, и т.д., имеет первоклассные структуры списка для содержания наборов результатов.

Медленный Выпуск

В некоторых кругах, реляционные соединения являются тайной, и люди запишут вложенные курсоры, а не простое соединение. Я рассматривал действительно эпические операции вложенного цикла, выписанные как партии и много курсоров. Нанесение поражения оптимизации RDBMS. И выполнение действительно медленно.

Простой SQL переписывает для замены вложенных циклов курсора соединениями, и единственный, плоский цикл курсора может сделать программы выполненными в 100-м время. [Они думали, что я был богом оптимизации. Все, что я сделал, было заменить вложенные циклы соединениями. Все еще используемые курсоры.]

Этот беспорядок часто приводит к обвинительному акту курсоров. Однако это не курсор, это - неправильное употребление курсора, это - проблема.

Выпуск

Размера Для действительно эпических наборов результатов (т.е. дамп таблицы в файл), курсоры важны. Основанные на наборе операции не могут осуществить действительно большие наборы результатов как единственный набор в памяти.

Альтернативы

я пытаюсь использовать уровень ORM как можно больше. Но это имеет две цели. Во-первых, курсорами управляет компонент ORM. Во-вторых, SQL разделяется от приложения в конфигурационный файл. Не то, чтобы курсоры плохи. Это - то кодирование всех, что они открывают, закрывают и выбирают, не значение - добавляет программирование.

73
ответ дан 24 November 2019 в 00:47
поделиться

Курсоры заставляют людей чрезмерно применить процедурное мышление к основанной на наборе среде.

И они МЕДЛЕННЫЕ !!!

От SQLTeam:

Обратите внимание на то, что курсоры являются САМЫМ МЕДЛЕННЫМ способом получить доступ к данным в SQL Server. Должен только использоваться, когда действительно необходимо получить доступ к одной строке за один раз. Единственная причина, о которой я могу думать для этого, состоит в том, чтобы назвать хранимую процедуру на каждой строке. В статья Cursor Performance я обнаружил, что курсоры более чем в тридцать раз медленнее, чем основанные на наборе альтернативы .

41
ответ дан 24 November 2019 в 00:47
поделиться

Существует ответ, выше которого говорит, что "курсоры являются САМЫМ МЕДЛЕННЫМ способом получить доступ к данным в SQL Server... курсоры более чем в тридцать раз медленнее, чем основанные на наборе альтернативы".

Этот оператор может быть верным при многих обстоятельствах, но как общий оператор это проблематично. Например, я хорошо использовал курсоры в ситуациях, где я хочу выполнить обновление или удалить операцию, влияющую на многие строки большой таблицы, которая получает постоянные производственные чтения. Выполнение хранимой процедуры, которая делает эти обновления, одна строка за один раз заканчивает тем, что была быстрее, чем основанные на наборе операции, потому что основанные на наборе операционные конфликты с операцией чтения и заканчивают тем, что вызвали ужасающие проблемы блокировки (и может уничтожить производственную систему полностью, в крайних случаях).

В отсутствие другого действия базы данных, основанные на наборе операции универсально быстрее. В производственных системах это зависит.

19
ответ дан 24 November 2019 в 00:47
поделиться

Оптимизатор часто не может использовать алгебру отношений для преобразования проблемы, когда метод курсора используется. Часто курсор является отличным способом решить проблему, но SQL является декларативным языком, и существует большая информация в базе данных, от ограничений, к статистике и индексам, которые означают, что оптимизатор имеет много опций решить проблему, тогда как курсор в значительной степени явно направляет решение.

9
ответ дан 24 November 2019 в 00:47
поделиться

Курсоры имеют тенденцию использоваться путем начала разработчиков SQL в местах, где основанные на наборе операции были бы лучше. Особенно то, когда люди изучают SQL после изучения, что традиционный язык программирования, "выполняют итерации по этим записям" менталитета, имеет тенденцию приводить людей использовать курсоры неуместно.

самые серьезные книги SQL включают главу, предписывающую использование курсоров; правильно написанные проясняют, что курсоры имеют свое место, но не должны использоваться для основанных на наборе операций.

существуют, очевидно, ситуации, где курсоры являются верным выбором или по крайней мере верным выбором.

9
ответ дан 24 November 2019 в 00:47
поделиться

В целом, потому что на реляционной базе данных, производительность кода с помощью курсоров является порядком величины, хуже, чем основанные на наборе операции.

6
ответ дан 24 November 2019 в 00:47
поделиться

В Oracle МН курсоры / курсоры SQL не приведут к блокировкам таблицы, и возможно использовать bulk-collecting/bulk-fetching.

В Oracle 10 часто используемый неявный курсор

  for x in (select ....) loop
    --do something 
  end loop;

выбирает неявно 100 строк за один раз. Явный bulk-collecting/bulk-fetching также возможен.

Однако МН курсоры / курсоры SQL являются чем-то вроде последнего средства, используют их, когда Вы не можете решить проблему с основанным на наборе SQL.

Другой причиной является распараллеливание, для базы данных легче параллелизировать большие основанные на наборе операторы, чем код императива строки строкой. Это - та же причина, почему функциональное программирование становится все более популярным (Haskell, F#, Lisp, C# LINQ, MapReduce...), функциональное программирование делает распараллеливание легче. Центральные процессоры числа на компьютер повышаются так, распараллеливание становится все больше проблемой.

8
ответ дан 24 November 2019 в 00:47
поделиться

Ответы выше не подчеркнули достаточно важность блокировки. Я не большой поклонник курсоров, потому что они часто приводят к блокировкам уровня таблицы.

6
ответ дан 24 November 2019 в 00:47
поделиться

Я соглашаюсь со статьей на этой странице:

http://weblogs.sqlteam.com/jeffs/archive/2008/06/05/sql-server-cursor-removal.aspx

2
ответ дан 24 November 2019 в 00:47
поделиться

Вы, возможно, вероятно, завершили свой вопрос после второго абзаца, вместо того, чтобы назвать людей "безумными" просто, потому что у них есть другая точка зрения, чем Вы делаете и иначе пытающийся дразнить профессионалов, у которых может быть очень серьезное основание для чувства способа, которым они делают.

относительно Вашего вопроса, в то время как существуют, конечно, ситуации, где курсор может требоваться, по моему опыту, разработчики решают, что курсором "должен" быть используемый FAR чаще, чем на самом деле имеет место. Шанс кого-то допускающего ошибку на стороне слишком большого использования курсоров по сравнению с не использованием их, когда они должны, НАМНОГО выше, по-моему.

1
ответ дан 24 November 2019 в 00:47
поделиться

Если это имеет значение я считал, что "тот" устанавливает курсор, будет работать, его основанный на наборе дубликат находится в рабочем общем количестве. По маленькой таблице скорость подведения итогов строки по порядку столбцами одобряют основанную на наборе операцию, но как увеличения таблицы размера строки курсор станет быстрее, потому что это может просто нести рабочее итоговое значение к следующей передаче цикла. Теперь , где необходимо сделать, рабочее общее количество является другим аргументом...

3
ответ дан 24 November 2019 в 00:47
поделиться

Можно ли отправить тот пример курсора или ссылку на вопрос? Существует, вероятно, еще лучший путь, чем рекурсивный CTE.

В дополнение к другим комментариям, курсоры при неподходящем использовании (который часто является) вызывают ненужную страницу/блокировки строки.

1
ответ дан 24 November 2019 в 00:47
поделиться

в основном 2 блока кода, которые делают то же самое. возможно, это - немного странный пример, но это подтверждает точку зрения. SQL Server 2005:

SELECT * INTO #temp FROM master..spt_values
DECLARE @startTime DATETIME

BEGIN TRAN 

SELECT @startTime = GETDATE()
UPDATE #temp
SET number = 0
select DATEDIFF(ms, @startTime, GETDATE())

ROLLBACK 

BEGIN TRAN 
DECLARE @name VARCHAR

DECLARE tempCursor CURSOR
    FOR SELECT name FROM #temp

OPEN tempCursor

FETCH NEXT FROM tempCursor 
INTO @name

SELECT @startTime = GETDATE()
WHILE @@FETCH_STATUS = 0
BEGIN

    UPDATE #temp SET number = 0 WHERE NAME = @name
    FETCH NEXT FROM tempCursor 
    INTO @name

END 
select DATEDIFF(ms, @startTime, GETDATE())
CLOSE tempCursor
DEALLOCATE tempCursor

ROLLBACK 
DROP TABLE #temp

единственное обновление берет 156 мс, в то время как курсор берет 2 016 мс.

0
ответ дан 24 November 2019 в 00:47
поделиться

Помимо проблем с производительностью (не), я думаю, что самый большой недостаток курсоров состоит в том, что их сложно отлаживать. Особенно по сравнению с кодом в большинстве клиентских приложений, где отладка имеет тенденцию быть сравнительно простой, а языковые функции гораздо проще. Фактически, я утверждаю, что почти все, что человек делает в SQL с курсором, вероятно, должно происходить в первую очередь в клиентском приложении.

2
ответ дан 24 November 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: