2014-05-19 2 views
0

데이터 검색을 수행하는 코드가 있습니다. 기본적으로 3 개에서 12 개의 SQL (oracle) read 문을 실행하여 객체에 대한 데이터를 검색합니다.다중 스레딩을 사용하여 SQL 문 실행

유감스럽게도 천천히 실행 중입니다. 특히 SQL 문이 없기 때문에 나는 그 중 많은 수가 있습니다. 문당 0.2 초 정도 걸리므로 코드 완성을 위해 2 초 이상 걸릴 수 있습니다.

나는 성능을 향상시키는 방법을 찾고있다. 한 가지 방법은 테이블 중 일부를 단일 쿼리로 병합하는 것입니다 (조합 된 결과를 0.5 초까지 줄일 수 있음). 그러나 특정 상황에서 데이터가있을 것이기 때문에 나머지를 병합하는 것은 의미가 없으며, 마샬링 할 데이터가있는시기를 결정하려고 할 때 까다로울 수 있습니다.

내 프로그램에 스레딩을 도입하려고합니다. 그래서 초기 쿼리 후에 다른 쿼리 각각에 대해 스레드를 생성하므로 동시에 실행됩니다. 그러나 나는 결코 쓰레딩을 사용하지 않았고 교착 상태 나 다른 구덩이에주의해야합니다.

현재 다른 쿼리는 결과를 SAME 개체의 여러 섹션으로 마샬링합니다. 이로 인해 문제가 발생 했습니까? 즉, 객체 내의 다른 섹션/필드를 통해 다른 스레드에서 같은 객체를 액세스/업데이트하고 있기 때문입니다. 모든 스레드가 완료된 후에 결과를 반환하고 개체로 마샬링하는 것이 더 좋을까요?

나는 이러한 유형의 질문이 일반적인 조언이 있기 때문에 대답하기가 어렵지만 누구나 그것이 좋은 생각이라고 생각하거나 다른 제안이 있다면 감사하겠습니까?

+3

이것이 XY 문제인지 궁금합니다. 사실상 단일 주체에 대한 데이터를 얻으려면 3-12 왕복을 수행해야합니까? 이 질문을 단일 쿼리로 가져올 수없는 방식으로 데이터가 계층에 분산되는 이유는 무엇입니까? 입출력 문제에서 쓰레드를 던지는 것은 보통 그렇게 잘 작동하지 않습니다. – spender

+0

그는 아직 IO 경계에 있지 않은 것처럼 보입니다. 스레딩은 어느 정도 도움이됩니다. – vav

+0

단일 개체 인스턴스 당 3 ~ 12 개의 쿼리를 실행하는 것이 맞습니까? DB (100, 1000, 1000000, ...)에서 정상적으로로드 된 객체 수 – ThinkJet

답변

0

독서 (선택) 만하고 있다면 - 교착 상태는 걱정하지 마십시오. 오라클 판독 값은 차단할 수 없습니다 (대부분). 오라클에 쿼리를 스레딩하는 가장 큰 문제는 연결을 처리하는 방법 일 것입니다. 연결을 만들려면 쿼리를 실행하고 연결을 닫습니다. 매우 나쁩니다. 연결 비용이 비쌉니다. 또한 제한적이기 때문에 논리를 실행하기 위해 1 백만 연결을 만들고 싶지는 않습니다.

결과적으로 일종의 연결 풀을 사용하고 쿼리를 대기열에 넣습니다.

또한 바인드 변수를 사용하고 문자열 연결을 사용하여 Oracle에 쿼리를 전달하지 않았 으면합니다.

일반적으로 모든 데이터를 수집 한 다음 (한 쿼리에서 더 낫습니다) 개체를 업데이트합니다. 당신은 또한 그것의 섹션에 귀하의 개체를 브레이크 고려할 수 있습니다.

+0

오라클 제공 업체가 C#/ADO.NET 연결 관리를 위해 반드시 필요한 연결 풀링을 구현하지 않는다는 것은 매우 어리 석다는 뜻입니까? 정말? 그렇지 않으면 새로운 연결을 여는 것이 싸다. v1 이후 .NET에서 COnnection 풀링은 표준입니다. – TomTom

+0

@TomTom - 10^6 연결을 열려고하면 대신 풀이 제공 될 것입니까? 내 X 연결이 자동으로 Y (<< X)와 대기열로 바운드되는 경계는 어디 있습니까? – vav

+0

@TomTom - 의견을 작성하는 경우 자신을 풀링을 구현하지 않으려는 경우 - 100 % 동의합니다. – vav

0

스레딩은 완벽하게 작동합니다. 2 년 전 나는 멀티 스트 레지/멀티 스레딩을 사용하여 오라클 데이터베이스에 데이터를 푸시하고 업데이트를 위해 일부 데이터를 가져 오는 프로젝트를 수행했습니다.

나는 기본적으로 단계적 접근 방식을 사용했다 (요청은 여러 단계를 거치고 거기에서 소비되고 새로운 데이터는 다음 단계로 넘어 간다). 그리고 모든 단계는 메시지를 취하고 처리 할 수있는 구성 가능한 스레드 풀을 사용했다. 새 메시지를 게시하십시오.

당시에는 약 200 만 개의 스레드에 가까운 분당 SQL 문을 처리하는 것이 좋았습니다. (실제로 Oracle Exadata를 사용하여 몇 가지 문제를 해결했습니다.)

그래서 멀티 스레딩은 "그냥 작동합니다"- 분명히 당신이 어떻게하는지 알면 아키텍처와 SQL 문을 좋고 비 차단으로 만들어야합니다. 데이터베이스는 일반적으로 다중 스레드를 완벽하게 계산할 수 있습니다.

이제 자세한 내용은 다음과 같습니다.

예 :

현재 다른 쿼리가 동일한 객체의 다른 부분에 결과 마샬링. 이 문제를 일으킬 것 (즉, 때문에 우리는 다른 스레드에서 동일한 개체를 업데이트/액세스하지만 개체 내에서 다른 섹션/필드?)

절대적으로 아무 문제만큼 :

  • 개체를 다음 단계로 이동하기 전에 모든 업데이트가 완료되고 업데이트가 완료됩니다.
  • 업데이트가 겹치지 않거나 카디널리티가 있습니다 (필요한 데이터가 2 개 있어야만 완료됩니다).

구현 세부 사항이며 이러한 경우 일반적인 대답을하기가 정말로 어렵습니다 (완전히 불가능). 특히 이것은 멀티 스레딩 101이므로 데이터베이스 액세스와는 아무런 관련이 없습니다.

일반적으로 스레드 수를 조정해야합니다. .NET 서버 자체는 그렇게 할 수 없습니다. 데이터베이스 서버가 병목 현상이 발생하더라도 CPU가 사용량이 많지 않고 더 많은 스레드를 생성하는 것을 볼 수 있기 때문입니다. 이것이 우리가 여러 단계로 진행 한 이유입니다. 그래서 스레드의 수를 조정할 수 있습니다. 마지막 단계에서는 적은 수의 스레드를 사용하여 집계 된 데이터를 임시 스테이징 테이블에 삽입하고 대량의 데이터를 이동하는 데 대량 삽입을 사용했습니다. 모든 진술에서 - 이것은 데이터베이스 측면을 완전히 과부하시키지 않는 약간의 튜닝 가능성을 요구할 것이다).

+0

먼저 응답 해 주셔서 감사합니다. 나는 대략적으로/신속하게 쓰레딩을 소개하는 코드를 추가하여 각각 6 개의 쓰레드가 서로 다른 테이블/데이터를 읽고 동일한 객체의 다른 부분을 업데이트했다. 내가 2 초 이상에서 0.6 초 미만으로 시간을 단축 했으므로이 문제에 대한 독특한 해결책 인 것처럼 보입니다. 하지만 한 가지 방법은 메인 스레드가 모든 자식 스레드가 종료 될 때까지 기다릴 수있는 쉬운 방법일까요? 메인 스레드가 자식 스레드 중 하나에서 데이터없이 완료된 경우가 두 번있었습니다. – user2026086