2013-04-12 3 views
1

약 500 명이 넘는 사용자를 지원하는 Windows 응용 프로그램 (.Net으로 작성)이 있습니다. 이 응용 프로그램에는 약 40k 레코드 (MS SQL Server에서)를 가져와 하루에 몇 번씩 실행하는 특정 기능이 있습니다.큰 데이터베이스 쿼리가 전체 시스템에 영향을 미침

그러나이 큰 쿼리를 실행하면 다른 사용자가 'Timing Out'인 것처럼 보입니다.이 쿼리는 큰 쿼리가 서버 리소스를 소모하여 다른 사용자가 시스템을 사용할 수 없도록하는 것 같습니다. 정확히.

40k 쿼리가 정확히 대량은 아니지만 상당히 크기가 있다고 생각하기 때문에 리소스 할당이 어떻게 작동하는지 이해하려고합니다.

우리의 애플리케이션 아키텍처는 UI입니다 -> 서비스 레이어 -> 웹 서비스 -> 데이터베이스

이 문제를 일으키는 또는 내 쿼리가 가능한 '잠금'SQL 데이터베이스 및 두지 않을 수 웹 서비스를 할 수 다른 사용자가 그와 상호 작용합니까?

SQL 쿼리는 문자 그대로 특정 테이블의 모든 레코드를 선택합니다 (이 테이블에는 다른 테이블에서 추출 된 데이터가 있으며 현재 약 40,000 개의 레코드가 있으며 테이블에는 약 50 개의 열이 있습니다).

SELECT * 
FROM MyTable 

꽤 많은 검색어입니다. 조인이없고 저장 프로 시저를 사용하고 있습니다.

+4

아마도 후자의 경우 쿼리는 데이터베이스 서버를 호깅합니다. 당신은 우리에게 쿼리와 관련 테이블 구조를 보여줄 수 있습니까? 아니면 실행 계획일까요? 쿼리가 매우 큰 결과 집합을 반환하여 웹 서버에서 메모리 사용량이 급증 할 수도 있습니다. – alexn

+0

당신은 어떤 질문을합니까? 얼마나 많은 테이블이 영향을 미치나요? 그것은 많은 조인을 가지고 있습니까? 테이블을 직접 사용하지 않고 뷰를 사용할 수 있습니까? 저장 프로 시저를 사용할 수 있습니까? 결과를 캐시 할 수 있습니까? –

+0

이 쿼리를 실행하고 SSMS의 모든 레코드를 반환하는 데 얼마나 오래 걸립니까? –

답변

1

나는 결정적인 것을 말하기에 충분한 정보가 없지만 몇 가지 추측/제안을 할 수 있습니다.

첫 번째로, 어떤 소스에서든지이 테이블에 대한 쓰기가없는 경우 ... 쿼리가 활성화되어있는 동안 with (nolock) 힌트를 추가하여 향상시킬 수 있습니다. 다시 말하지만 : 쿼리가 진행되는 동안 테이블이 변경되지 않은 경우 또는 더러운 읽기로 인해 오래된/잘못된 결과를 생성하는 쿼리에 익숙한 경우에만이 작업을 수행하십시오.

또한 검색어에 대한 설명에서 '꽤 많이'라는 문구는 무언가가 그 외에도 표시 될 수 있음을 나타냅니다. 여전히 간단하지만 뭔가 있습니다. ORDER BY 절이 있으면 기본 키와 순서를 일치 시키거나 기본 키를 필요한 순서로 맞추면 도움이 될 것입니다.

웹 서비스 계층과 병목 현상에 대한 데이터베이스는 매우 쉽게 결정할 수 있어야합니다. 이것이 웹 서비스라면 CPU, RAM 또는 네트워크 I/O가 서버에서 서비스 계층에 대해 100 %로 급증하여 다른 클라이언트를 빠져 나올 수 있다는 것을 알 수 있습니다. 서비스 네트워크 계층은 모든 데이터를 두 번 처리해야하기 때문에 서비스 일 수 있습니다. 일단 데이터베이스에서 데이터를 가져 오면 다시 한 번 최종 사용자 클라이언트에 다시 전송하므로 두 번 데이터를 처리해야하기 때문입니다. 따라서 데이터 사용에는 작은 승수 효과가 있습니다. 그러나 그 효과가 있다고하더라도, 나는 데이터베이스가 범인이라고 생각한다.

이 데이터가 오래 되었다면 서비스 계층에 코드를 추가하여 캐시하는 것이 좋습니다.

+0

감사합니다. Joel, 사과드립니다. 오해라고 생각하기 때문입니다. 테이블에 대한 쓰기가 있지만 데이터를 가져 오는 쿼리에는 없습니다. 혼란에 대해 사과드립니다. with (nolock)를 사용하면 쿼리 중에 쓰기가 시도 될 경우 예외가 발생합니까? – mint

+0

아니요. 그러나 예기치 않은 데이터가 반환 될 수 있습니다. –

1

MyTable에서 *를 선택하면 테이블을 잠그기 때문에 다른 모든 사람이 기다려야합니다.

먼저 확인할 사항 - 코드를 어떻게 읽었습니까? 데이터 보관함을 사용한다면, 그것을 닫을 때까지 테이블을 잠글 것이다. SQLDataAdapter를 사용하여 테이블에 넣습니다. 그것은 실제로 데이터를 가져 오는 데 걸리는 시간 동안 테이블을 잠근 상태로 둘 것입니다.

또 다른 것은 다이 하드가 당기면 *하지 말라고 말할 것입니다. 필요한 필드 만 가져옵니다.

'더티 (dirty)'데이터 (커밋되지 않은 데이터)가 마음에 들지 않으면 select * from mytable with (nolock)을 사용하십시오. 그것은 아직 커밋되지 않은 것을 얻을 것이라는 것을 의미합니다. 그러나 테이블이 끊임없이 변하지 않는다면 그것은 문제가되어야합니다.

0

40k 행 x50 열은 500 이상의 사용자가있는 실시간 시스템에서 추출 할 수있는 엄청난 양의 데이터입니다. 50 열의 평균 열 크기가 20 바이트라고 가정하면 약 800k의 데이터를 검색하지만 varchar의 100 바이트 길이가 길면 크기가 상당히 커집니다.

왜 거대한 쿼리가 필요한지 질문합니다. 분명히 누군가가 화면에서 편안하게 볼 수있는 너무 많은 데이터입니다. 다른 데이터 저장소에 데이터를 공급하는 경우 부재 중 시간 만 실행하거나 백그라운드에서 배치로 추출하거나 별도의 서버에 데이터를 복제하는 프로세스가 있어야합니다.

+0

내부 LAN을 통한 800K는 아무 것도 아닙니다. –

+0

그래, 데이터 추출을 위해, 사용자가 '라이브 쿼리'로보기 위해 끌어 올리는 것이 아닙니다. – mint

+0

@Joel Coelhoorn 데이터가 LAN에서 처리되고 많은 수의 처리 및 I/O 요청을 처리하는 LAN에서 중요한 역할을 할 때 LAN 자체에 문제는 없지만. 또한 800k는 conserative 수치가 될 수 있습니다. –

관련 문제