2011-01-20 2 views
8

우리는 이런 작은 선물을 보이는 검색 화면과 시스템을 개발했습니다 . 상태, 채널, 언어, 캠페인 유형을 원하는대로 조합하여 사용할 수 있습니다. 그런 다음 이름 등으로 범위를 좁힐 수 있습니다.ASP.NET/SQL 2008 성능 문제

그런 다음 검색을 완료하고 리드가 아래쪽에 나타나면 헤더를 정렬 할 수 있습니다.

쿼리는 Ragingum을 사용하여 페이징 체계를 수행하므로 한 번에 70 개의 행만 반환합니다.

문제점

우리는 70 행, IO의 엄청 많이 반환하고 있고 정렬이 진행되고 있지만. 이것은 물론 이해가됩니다.

이렇게하면 항상 디스크 대기열에 약간의 스파이크가 발생합니다. 3 백만 리드를 기록 할 때 더 느려지 기 시작했으며 이제는 5에 가까워지고 있습니다. 디스크 대기열 페그는 때로는 2 ~ 2 회 연속으로 작동합니다.

실제로는 여전히 작동 할 수 있지만이 시스템에는 시간에 민감한 프로세스가있는 또 다른 영역이 있습니다. 웹 서비스라는 단순성을 위해 응답을 매우 신속하게 제공해야하거나 시스템에서 시간 초과를 유발할 수 있습니다. 다른 끝. 디스크 대기열 스파이크로 인해 해당 부분이 다운되어 다운 타임이 발생합니다. 최종 결과는 실제로 우리의 자동화 된 VoiceXML 기반 IVR에서 전화를 끊었습니다. 이는 우리에게 매우 나쁜 것입니다. 최소한으로 시스템에 리드의 수를 줄일 수

  • 유지 보수 작업을 : 우리는 우리가 시도했습니다

    을 시도했다

    .

  • 명백한 색인을 추가하여 도움을 받았습니다.
  • 프로파일 러에서 인덱스 튜닝 마법사를 실행하고 대부분의 제안 사항을 적용했습니다. 그들 중 하나는 인덱스 내에서 전체 테이블을 다소 재현 할 예정 이었기 때문에 나는 그것을 약간 덜하기 위해 손으로 조정했습니다.
  • 더 많은 RAM을 서버에 추가했습니다. 그것은 조금 낮았지만 지금은 항상 8 기가 유휴와 같은 것을 가지고 있고 SQL 서버는 8 기가를 사용하도록 구성되어 있지만 2와 3을 사용하지 않습니다. 나는 그 이상한 것을 발견했습니다. 왜 전체 테이블을 RAM에 넣는 것이 아닌가? 단 500 만 리드이고 충분한 공간이 있습니다.
  • 쿼리 실행 계획에 쏟아졌습니다. 나는이 시점에서 인덱스가 대부분 자신의 일을하는 것처럼 보입니다. 정렬 단계에서 작업의 약 90 %가 일어나고 있습니다.
  • 리드 테이블을 다른 실제 드라이브로 분할하는 것으로 간주되지만 리소스가 필요하지 않으므로 필요하지는 않습니다. 서버가이 문제를 처리 할 수 ​​있어야합니다 같은 날의 끝으로

...

부분은 느낀다. 5 백만 레코드는 그 서버의 힘을 감안할 때 그렇게 많지는 않습니다. 16 기가의 RAM을 가진 괜찮은 쿼드 코어입니다.그러나 정렬 부분이 소수의 행을 반환하기 위해 수백만 행을 만지게 한 것을 볼 수 있습니다.

그래서 이런 상황에서 무엇을 했습니까? 필자의 본능은 우리가 일부 기능을 축소해야한다는 것입니다.하지만이 기능을 그대로 유지하면 사업부와의 전쟁을 저축 할 수 있습니다.

미리 감사드립니다.

+0

GUID를 검색하고 있습니까? 클러스터 된 인덱스 란 무엇입니까? 서버에서 SSD를 고려한 적이 있습니까? 와일드 카드 검색을하고 있습니까? 그렇다면 varchars를 앞뒤로 색인화해야 할 수도 있습니다. – Matthew

+0

@Matthew PK : GUID 없음. 클러스터형 인덱스는 기본 키 (LeadID (int))입니다. 솔리드 스테이트 드라이브에 관해서는 ... 음, 돈을 버는 것은 나의 마지막 도랑 옵션이되어야합니다. 그러나 그것은 내 마음에 있습니다. :) –

+0

클라이언트에서 전체 결과 세트와 페이징을 반환하는 방법은 무엇입니까? 사용자로서, 나는 페이지를 넘을 때마다 기다리는 것보다 2 초 앞당겨 기다리는 편이 낫다. – Matthew

답변

3

SQL 병목 현상은 자주 SQL 쿼리를 개선하여 향상시킬 수 있습니다. 이러한 모습을 알지 못하면 일정 기간 동안 사용자가 입력하는 운영 데이터 저장소 나 데이터웨어 하우스를 만드는 것을 고려하십시오.

때로는 복잡한 관계형 데이터베이스를 병합하는 것이 좋습니다. 모델이 매우 평탄하기 때문에 쿼리를 훨씬 빠르게 실행할 수 있으며 쿼리를 최적화하는 것이 훨씬 쉬워집니다. 따라서 데이터베이스 서버를 확장 또는 확장해야하는지 여부를 쉽게 판별 할 수 있습니다. 수용력과 성장 분석은 그 부름을하는 데 도움이 될 수 있습니다.

트랜잭션/고도로 정규화 된 데이터베이스는 일반적으로 ODS 또는 데이터웨어 하우스만큼 확장 가능하지 않습니다.

편집 : 데이터베이스에 보내는 쿼리를 최적화하는 방법을 찾는 것이 아니라 ORM이 최적화되어있어 조사할만한 가치가있을 수도 있습니다. 아마도 ORM을 우회하여 더 나은 실적을 얻으려면 쿼리를 완전히 제어 할 수있는 방법 중 하나 일 수 있습니다.

+0

ORM이 얼굴에 떨어지는 또 다른 장소. –

+0

예, 특정 시나리오에서는 ORM이 적합하지 않을 수 있습니다. 아마도 솔루션이 ORM 지향을 유지해야 할 경우 단순한 개체 계층을 사용하여 쿼리를 구성하는 단순화 된 데이터베이스 모델이 될 수 있습니다. 나는 최소한의 저항의 경로가 기존의 ORM 쿼리를 최적화하는 방법을 조사하는 것일 수 있다고 생각합니다. –

2
  1. 임시 쿼리가 가장 가능성이 실행됩니다 결정 또는 저장 프로 시저와 검색 조건을 제한 .. 당신이 데이터를 요약 할 수 있는가? .. 데이터웨어 하우스 등이
    응용 프로그램을 처리합니다.
  2. 테이블 스캔을 피하기 위해 검색과 관련된 각 컬럼에 인덱스를 작성하십시오.
  3. 식에 조각을 만듭니다.
  4. 은 더 많은 리드가로드 될 때마다 주기적으로 데이터를 재구성하고 통계를 업데이트합니다.
  5. 쿼리 (결과 집합)로 만든 임시 파일을 램 디스크에 넣습니다.
  6. Informix OnLine과 같은 고성능 RDBMS 엔진으로 마이그레이션하는 것이 좋습니다.

  7. 쿼리가 계속 실행되는 동안 결과 세트에서 N 개의 행을 표시하기 위해 다른 스레드를 시작하십시오.
+2

좋은 물건 ... 또한이 오류가 표시되지 않는 동안 단계가 계속 적용됩니다. http://stackoverflow.com/questions/4719841/system-data-sqlclient-sqlexception-timeout-expired#4719892 –

+0

신중하게 쿼리를 제어하고 있습니다. ORM이이를 수행하지 않는다고 생각합니다. 과도한 인덱스로 인해 주어진 유형의 검색에 대해 "최상의"인덱스를 선택하는 대신 DB가 "모든 거래의"잭을 사용하려고 할 수 있습니다. – Matthew

+0

이것은 정말 흥미 롭습니다. 램 디스크를 만드는 데 사용하는 특정 도구가 있습니까? Google은 RamDisk와 RamDisk plus를 발견했습니다. –

2

ORM이 어떻게 쿼리를 작성하는지 고려하십시오. 검색 성능이 좋지 않은 경우 저장 프로 시저를 사용하여 결과를 반환하거나 필요한 경우 검색 기준이 사용되는 여러 저장 프로 시저를 시도해 볼 수 있습니다.