programing

커서에 무슨 문제가 있습니까?

goodsources 2023. 10. 13. 22:05
반응형

커서에 무슨 문제가 있습니까?

SQL Server 개발자들은 일부 상황을 제외하고는 커서를 잘못된 방법으로 간주합니다.그들은 SQL 엔진이 절차적 구성이고 RDBMS의 Set-based 개념을 물리치기 때문에 Cursor가 최적으로 사용하지 않는다고 생각합니다.

그러나 Oracle 개발자들은 커서에 반대하는 것을 권장하지 않는 것 같습니다.Oracle의 DML 문 자체는 암시적 커서입니다.

접근 방식이 다른 이유는 무엇입니까?이 두 제품이 만들어지는 방식 때문인가요, 아니면 이 조언은 두 제품 모두에 적용되는 건가요?

입니다에서 입니다.Oracle그리고 안에MS SQL.

커서는 행 단위로 검색할 수 있는 안정적인 결과 세트를 유지하기 위한 것입니다.쿼리가 실행되면 암묵적으로 생성되고 쿼리가 완료되면 닫힙니다.

이러한 합니다이라는 합니다.locks,latches,memory,심지어.disk space.

이러한 자원은 더 빨리 해방될수록 더 좋습니다.

커서를 열어두는 것은 냉장고 문을 열어두는 것과 같습니다.

여러분은 필요 없이 몇 시간 동안 그것을 하지는 않지만, 냉장고를 절대 열지 말아야 한다는 것을 의미하는 것은 아닙니다.

이는 다음을 의미합니다.

  • 한 줄 한 것입니다.SQLSUM대신.
  • 에서 첫 를 가져오는은 아닙니다. 하는 것입니다. 다음을 추가합니다.rownum <= 10

,기타.

에 관해서는Oracle 높은 합니다가 합니다.SQL/PLSQL context switch입니다 SQL커서에서 쿼리합니다.

스레드 간에 많은 양의 데이터를 전달하고 스레드를 동기화하는 작업이 포함됩니다.

은 입니다에서 중 입니다.Oracle.

이러한 동작으로 인해 발생할 수 있는 가장 명확하지 않은 결과 중 하나는 Oracle에서 트리거가 발생하지 않도록 해야 한다는 것입니다.

DML기능은 커서를 열고 업데이트된 행을 선택하고 이 커서의 각 행에 대해 트리거 코드를 호출하는 것과 같습니다.

가 존재하는 빈 만으로도(도) A 의 수 있습니다.DMLn10 times혹은 그 이상.

에 대한 테스트 스크립트10g:

SQL> CREATE TABLE trigger_test (id INT NOT NULL)
  2  /

Table created

Executed in 0,031 seconds
SQL> INSERT
  2  INTO   trigger_test
  3  SELECT level
  4  FROM   dual
  5  CONNECT BY
  6     level <= 1000000
  7  /

1000000 rows inserted

Executed in 1,469 seconds
SQL> COMMIT
  2  /

Commit complete

Executed in 0 seconds
SQL> TRUNCATE TABLE trigger_test
  2  /

Table truncated

Executed in 3 seconds
SQL> CREATE TRIGGER trg_test_ai
  2  AFTER INSERT
  3  ON trigger_test
  4  FOR EACH ROW
  5  BEGIN
  6     NULL;
  7  END;
  8  /

Trigger created

Executed in 0,094 seconds
SQL> INSERT
  2  INTO   trigger_test
  3  SELECT level
  4  FROM   dual
  5  CONNECT BY
  6     level <= 1000000
  7  /

1000000 rows inserted

Executed in 17,578 seconds

1.47초s17.57아무 것도 하지 않는 빈 트리거가 있는 초.

MSDN으로부터:Cursor 구현

커서를 사용하는 것은 기본 결과 집합을 사용하는 것보다 효율성이 떨어집니다.기본 결과 집합에서 클라이언트에서 서버로 전송되는 패킷은 실행할 문이 포함된 패킷뿐입니다.서버 커서를 사용할 때, 각 FETCH 문은 클라이언트에서 서버로 전송되어야 하며, 여기서 FETCH 문은 파싱되고 실행 계획으로 컴파일되어야 합니다.

Transact-SQL 문이 클라이언트 응용 프로그램에서 사용 가능한 메모리에 캐시할 수 있는 비교적 작은 결과 집합을 반환하고 전체 결과 집합을 검색해야 한다는 문을 실행하기 전에 알고 있는 경우 기본 결과 집합을 사용합니다.애플리케이션의 기능을 지원하기 위해 커서 작업이 필요하거나 결과 집합의 일부만 검색될 가능성이 있는 경우에만 서버 커서를 사용합니다.

저는 오라클 DBA가 아니기 때문에 구현이 어떻게 다른지 말할 수 없습니다.그러나 프로그래밍의 관점에서 볼 때 세트 기반 작업은 커서에서 결과를 처리하는 것보다 거의 항상 빠릅니다.

저는 항상 악이 있는 커서라는 말을 들었지만 성능이 좋지 않아 항상 MS SQL Server 전문가로부터 들었습니다.Oracle의 PL/SQL과 관련하여 커서사용할 때 다음과 같은 문구가 있습니다.

커서를 사용하지 않으면 구문 분석이 반복됩니다.바인딩 변수를 사용하지 않으면 모든 SQL 문에 대해 하드 구문 분석이 수행됩니다.이것은 성능에 큰 영향을 끼치고 있으며, 전혀 확장할 수 없습니다.커서를 열고 여러 번 실행하는 바인딩 변수와 함께 커서를 사용합니다.동적 SQL을 생성하는 응용 프로그램을 의심해 보십시오.

모든 작업에서 커서암묵적으로 생성되므로 필요할 때 커서를 사용하는 것이 성능에 그다지 부담이 되지 않는 것 같습니다. :)

Oracle의 구현은 Sybase(MS SQL Server의 제네시스)보다는 Postgres(포스트그레스)에 가깝기 때문에 작업마다 성능이 다르다는 것을 기억하십시오.가능하다면 백엔드를 교환할 수 있는 시스템의 성능을 조정하기 위해 서두르는 것을 피하고, 두 가지를 모두 사용해야 한다면 최소한 공통분모를 사용해야 합니다. /tangential_topic

누군가가 더 자세히 설명할 수 있을 것이라고 확신하지만, 기본적으로 SQL 서버의 커서는 느립니다.

다른 답변은 커서의 성능 문제를 정확하게 지적하지만 SQL 및 관계형 데이터베이스가 세트 기반 작업에 가장 적합하고 커서가 기본적으로 반복 작업에 적합하다는 점은 언급하지 않습니다.커서를 사용하여 더 쉽게 수행할 수 있는 몇 가지 작업(광범위한 의미에서)이 있지만 SQL로 작업할 때는 항상 데이터 집합으로 작업하는 것을 고려해야 합니다.코드화기가 집합 기반 연산을 사용하여 작업을 수행하는 방법을 파악하지 못했기 때문에 커서가 잘못 사용되는 경우가 많습니다.

언급URL : https://stackoverflow.com/questions/743183/what-is-wrong-with-cursors

반응형