[SQL] 왜 사람들이 너무 많은 SQL 커서를 싫어합니까? [닫은]
SQL왜 사람들이 너무 많은 SQL 커서를 싫어합니까? [닫은]
나는 때문에 오버 헤드 및 불편에 커서를 사용하지 않도록하고자 이해할 수 있지만, 사람들이 하나를 사용하는 것을 방지하기 위해 많은 노력을가는 위치에가는 심각한 커서 공포증 매니아있을 것 같습니다.
예를 들어, 하나의 문제는, (32)에 처리 할 수있는 행의 경우에도이 한계 비록 수를 커서 공통 테이블 식 (CTE) 재귀 정의 함수와 재귀 쿼리를 사용하여 제안 된 허용 대답에 분명히 사소한 일을 수행하는 방법 질문 (인해 SQL 서버 재귀 함수 호출 한도). 이 시스템 수명에 대한 끔찍한 솔루션 말할 것도없고 간단한 커서를 사용하지 않는 단지 엄청난 노력으로 저를 친다.
미친 증오의 수준에 대한 이유는 무엇입니까? 일부 '지적 권위는'커서에 대한 파트와를 발표 했습니까? 어린이 또는 무언가의 도덕을 손상 커서의 중심부에 일부 말할 수없는 악마의 속임수를합니까?
더 담당자보다 대답에 관심이 위키 질문.
관련 정보 :
빠른 SQL 서버 앞으로 커서
편집 : 좀 더 정확한하자 : 나는 커서 대신 정상적인 관계 연산의 사용해서는 안 이해; 그 생각할 필요 없다. 내가 이해하지 못하는 것은 그들이 cooties 또는 무언가를 가지고있는 것처럼 사람들이 커서 간단한 및 / 또는보다 효율적인 솔루션입니다 경우에도 피할 커서에 절대로 안돼요 밖으로 자신의 길을 가고있다. 그것은 배플 그 비이성적 인 증오 나 아닌 명백한 기술적 효율성이다.
해결법
-
==============================
1.커서가있는 "오버 헤드는"단순히 API의 일부입니다. 커서 어떻게 후드 아래에있는 RDBMS 작업의 일부입니다. 종종 테이블을 만들고 INSERT가 SELECT 문이 있고, 구현은 분명 내부 커서 구현입니다.
커서가있는 "오버 헤드는"단순히 API의 일부입니다. 커서 어떻게 후드 아래에있는 RDBMS 작업의 일부입니다. 종종 테이블을 만들고 INSERT가 SELECT 문이 있고, 구현은 분명 내부 커서 구현입니다.
"집합 기반 연산자를"높은 수준을 사용하면 적은 API의 전후를 의미하는 하나의 결과 집합에 커서 결과를 번들.
커서는 일류 컬렉션을 제공하는 현대적인 언어를 선행한다. 널리 이용 될 수있다 "모음"에 대한 개념이 없었기 때문에 올드 C, COBOL, 포트란 등이 한 번에 처리 행을 하나했다. 자바 등 C #, 파이썬, 결과 집합을 포함하는 일류 목록 구조를 가지고있다.
슬로우 문제
일부 원에서 관계형 조인은 신비하고, 사람들은 간단한 가입보다는 중첩 된 커서를 작성합니다. 나는 많은 및 커서의 많은으로 기입 진정한 서사시 중첩 루프 작업을 보았다. RDBMS와 최적화를 물리 치고. 그리고 정말 느리게 실행.
간단한 SQL 조인과 하나의 평면 커서 루프가 100 시간에 실행되는 프로그램을 만들 수 있습니다 중첩 된 커서 루프를 대체하기 위해 다시 작성합니다. [그들은 내가 최적화의 신 생각했다. 모든 I 조인과 중첩 루프를 교체했다 않았다. 여전히 커서를 사용했습니다.]
이 혼란은 종종 커서의 기소로 연결됩니다. 그러나,이 문제의 커서의 오용의 커서 아니다.
크기 문제
정말 서사시 결과 세트 (즉, 파일에 테이블을 덤프), 커서는 필수적이다. 세트 - 기반 연산은 메모리의 단일 집합으로서 실제로 큰 결과 집합을 구체화 할 수 없다.
대안
나는 가능한 한 같은 ORM 층을 사용하려고합니다. 하지만 그 두 가지 목적이있다. 첫째, 커서는 ORM 구성 요소에 의해 관리됩니다. 둘째, SQL은 구성 파일에 애플리케이션으로부터 분리된다. 그것은 커서가 나쁜 것이 아니다. 이 닫히고 페치는 부가가치 프로그래밍 아니라, 모든 사람을 코딩 열립니다이다.
-
==============================
2.커서는 사람들이 지나치게 세트 기반 환경에 절차 적 사고 방식을 적용합니다.
커서는 사람들이 지나치게 세트 기반 환경에 절차 적 사고 방식을 적용합니다.
그리고 그들은 SLOW 있습니다!
SQLTeam에서 :
-
==============================
3.라고하는 위의 대답 "커서는 SQL 서버의 내부 데이터에 액세스 가장 느린 방법은 커서가 느리게 설정을 기반으로 대안보다 더 이상 서른 배 ...."있다
라고하는 위의 대답 "커서는 SQL 서버의 내부 데이터에 액세스 가장 느린 방법은 커서가 느리게 설정을 기반으로 대안보다 더 이상 서른 배 ...."있다
이 문장은 많은 상황에서 사실 일 수 있지만, 담요 문으로는 문제가 있습니다. 예를 들어, 내가 생산 읽기 상수를 받고있는 큰 테이블의 많은 행에 영향을 미치는 업데이트 나 삭제 작업을 수행하려는 상황에서 커서 잘 사용했습니다. 때문에 집합 기반 작업 읽기 작업과 충돌하고 끝나는 끔찍한 잠금 문제를 일으키는 최대 속도 설정 기반 작업에 비해되는 최대 시간 끝에 이러한 업데이트 한 행을 수행하는 저장 프로 시저를 실행 (그리고 완전히 생산 시스템을 죽일 수있다, 극단적 인 경우).
기타 데이터베이스 작업이없는 경우에, 세트 기반 작업은 보편적으로 빠릅니다. 생산 시스템에서는 따라 달라집니다.
-
==============================
4.커서는 집합 기반 작업이 더 좋을 것이다 장소에서 SQL 개발자를 시작으로 사용되는 경향이있다. 사람들이 기존의 프로그래밍 언어를 학습 한 후 SQL을 배울 특히 때 "으로 반복이 기록을 통해"사고 방식이 부적절하게 사용 커서 사람들을 인도하는 경향이있다.
커서는 집합 기반 작업이 더 좋을 것이다 장소에서 SQL 개발자를 시작으로 사용되는 경향이있다. 사람들이 기존의 프로그래밍 언어를 학습 한 후 SQL을 배울 특히 때 "으로 반복이 기록을 통해"사고 방식이 부적절하게 사용 커서 사람들을 인도하는 경향이있다.
대부분의 심각한 SQL 책은 커서의 사용을 출판 금지를 명령 장을 포함한다; 잘 쓰여진 사람은 커서 자신의 자리를 가지고 있지만 집합 기반 작업에 사용되지 않도록 삭제합니다.
커서가 올바른 선택입니다 상황, 또는 적어도 올바른 선택은 분명히있다.
-
==============================
5.옵티마이 저는 종종 커서 방법을 사용하면 문제를 변환 관계 대수를 사용할 수 없습니다. 종종 커서가 문제를 해결하는 좋은 방법이지만, SQL은 선언적 언어, 데이터베이스에있는 많은 정보는 옵티마이를 해결하기 위해 많은 옵션을 가지고 있다는 것을 의미 통계 및 인덱스에, 제약 조건에서,이 문제 커서가 거의 명시 적으로 해결책을 지시하는 반면.
옵티마이 저는 종종 커서 방법을 사용하면 문제를 변환 관계 대수를 사용할 수 없습니다. 종종 커서가 문제를 해결하는 좋은 방법이지만, SQL은 선언적 언어, 데이터베이스에있는 많은 정보는 옵티마이를 해결하기 위해 많은 옵션을 가지고 있다는 것을 의미 통계 및 인덱스에, 제약 조건에서,이 문제 커서가 거의 명시 적으로 해결책을 지시하는 반면.
-
==============================
6.오라클 PL에서 / SQL 커서는 테이블 잠금을 초래하지 않습니다 대량 수집 / 대량 페치를 사용하는 것이 가능하다.
오라클 PL에서 / SQL 커서는 테이블 잠금을 초래하지 않습니다 대량 수집 / 대량 페치를 사용하는 것이 가능하다.
오라클 10 자주 사용 암시 적 커서에서
for x in (select ....) loop --do something end loop;
한 번에 암시 적으로 100 행을 가져옵니다. 명시 적 대량 수집 / 벌크 페칭도 가능하다.
그러나 PL / SQL 커서는 최후의 수단 일 수 있습니다 당신은 세트 기반의 SQL에 문제를 해결할 수없는 경우를 사용합니다.
또 다른 이유는 데이터베이스가 행 단위 필수 코드보다 큰 집합 기반의 문을 병렬화하기가 쉽습니다, 병렬화입니다. 그것은 함수형 프로그래밍은 점점 더 인기가된다 이유 같은 이유입니다 (하스켈, F #, 리스프, C # LINQ, 맵리 듀스는 ...), 함수형 프로그래밍은 쉽게 병렬화한다. 병렬화가 더욱 더 문제가된다, 그래서 컴퓨터 당 수의 CPU는 증가하고있다.
-
==============================
7.일반적으로, 때문에 관계형 데이터베이스에 코드를 사용하여 커서의 성능은 집합 기반 작업보다 더 크기 순서입니다.
일반적으로, 때문에 관계형 데이터베이스에 코드를 사용하여 커서의 성능은 집합 기반 작업보다 더 크기 순서입니다.
-
==============================
8.대답은 위에서 충분히 잠금의 중요성을 강조하지 않았습니다. 그들은 종종 테이블 레벨 잠금이 발생할 때문에 커서의 큰 팬이 아니에요.
대답은 위에서 충분히 잠금의 중요성을 강조하지 않았습니다. 그들은 종종 테이블 레벨 잠금이 발생할 때문에 커서의 큰 팬이 아니에요.
-
==============================
9.나는 "일"의 장소 커서가 밖으로의 설정 기반의 대응을 수행 읽었습니다 무엇의 가치가 들어 누계입니다. 작은 테이블에 걸쳐 열별로 순서를 통해 행을 합산의 속도는 집합 기반 작업을 선호하지만 단순히의 다음 패스에 누적 합계 값을 수행 할 수 있기 때문에 행 크기의 테이블이 증가함에 따라 커서가 빠르게 될 것입니다 고리. 이제 당신이해야 할 경우 실행중인 총 다른 인수는 ...
나는 "일"의 장소 커서가 밖으로의 설정 기반의 대응을 수행 읽었습니다 무엇의 가치가 들어 누계입니다. 작은 테이블에 걸쳐 열별로 순서를 통해 행을 합산의 속도는 집합 기반 작업을 선호하지만 단순히의 다음 패스에 누적 합계 값을 수행 할 수 있기 때문에 행 크기의 테이블이 증가함에 따라 커서가 빠르게 될 것입니다 고리. 이제 당신이해야 할 경우 실행중인 총 다른 인수는 ...
-
==============================
10.나는이 페이지의 기사에 동의 :
나는이 페이지의 기사에 동의 :
http://weblogs.sqlteam.com/jeffs/archive/2008/06/05/sql-server-cursor-removal.aspx
-
==============================
11.성능 (비) 문제의 외부, 나는 가장 큰 커서 실패하는 것은 그들이 디버깅 고통스러운 생각합니다. 디버깅이 비교적 쉬운 경향이 있고 언어 기능을 훨씬 쉽게하는 경향이 어디 특히 대부분의 클라이언트 응용 프로그램 코드에 비교했다. 사실, 난 아마 처음에 클라이언트 응용 프로그램에서 발생한다 거의 아무것도 하나가 커서 SQL에서하고있는 것을 주장한다.
성능 (비) 문제의 외부, 나는 가장 큰 커서 실패하는 것은 그들이 디버깅 고통스러운 생각합니다. 디버깅이 비교적 쉬운 경향이 있고 언어 기능을 훨씬 쉽게하는 경향이 어디 특히 대부분의 클라이언트 응용 프로그램 코드에 비교했다. 사실, 난 아마 처음에 클라이언트 응용 프로그램에서 발생한다 거의 아무것도 하나가 커서 SQL에서하고있는 것을 주장한다.
-
==============================
12.당신은 질문이 커서 예 또는 링크를 게시 할 수 있습니까? 재귀 CTE보다 더 좋은 방법은 아마도이있다.
당신은 질문이 커서 예 또는 링크를 게시 할 수 있습니까? 재귀 CTE보다 더 좋은 방법은 아마도이있다.
불필요한 페이지 / 행 잠금 원인 다른 코멘트, 잘못 사용되는 커서 (보통이다) 이외에.
-
==============================
13.당신은 아마 오히려 당신이 그렇지 않으면 그들이하는 방식을 느낌에 아주 좋은 이유가있을 수 있습니다 모의 전문가에게 것보다 그들이 다른 관점을 가지고 있기 때문에 단순히 사람 "정신"을 호출하는 대신, 두 번째 단락 후 질문을 체결 할 수 있었다.
당신은 아마 오히려 당신이 그렇지 않으면 그들이하는 방식을 느낌에 아주 좋은 이유가있을 수 있습니다 모의 전문가에게 것보다 그들이 다른 관점을 가지고 있기 때문에 단순히 사람 "정신"을 호출하는 대신, 두 번째 단락 후 질문을 체결 할 수 있었다.
내 경험 개발자의 커서가 요구 될 수있는 상황이 확실히 존재하는 동안 귀하의 질문에 관해서는, 커서는 FAR 더 자주 실제로 경우보다 사용 "해야한다"고 결정한다. 때 정상적으로 사용하지 않을 대 커서 너무 많이 사용의 측면에서 사람의 죄를 범하고의 기회가 훨씬 더 내 의견이다.
-
==============================
14.같은 일을 코드의 기본적으로 2 개 블록. 어쩌면 조금 이상한 예제하지만 점을 증명한다. SQL 서버 2005 :
같은 일을 코드의 기본적으로 2 개 블록. 어쩌면 조금 이상한 예제하지만 점을 증명한다. SQL 서버 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
커서가 2,016 밀리 취하면서 하나의 업데이트는 156 밀리합니다.
from https://stackoverflow.com/questions/287445/why-do-people-hate-sql-cursors-so-much by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 서로 값을 하나 개의 MySQL의 테이블을 업데이트 (0) | 2020.04.05 |
---|---|
[SQL] 자바의 SQL 문자열을 구축 깨끗한 방법 (0) | 2020.04.05 |
[SQL] 어떻게 SELECT INTO OUTFILE와 MySQL을 errcode를 13 주위를받을 수 있나요? (0) | 2020.04.05 |
[SQL] 가장 좋은 방법은 "비어 있거나 null 값"을 확인합니다 (0) | 2020.04.05 |
[SQL] 진수 컬럼에 돈을 저장 - 어떤 정밀도와 스케일? (0) | 2020.04.05 |