문제

다음은 내 쿼리입니다.

select word_id, count(sentence_id) 
from sentence_word 
group by word_id 
having count(sentence_id) > 100;

테이블 문장에는 3 개의 필드, WordId, SentenceID 및 기본 키 ID가 포함되어 있습니다. 350k+ 행이 있습니다. 이 쿼리는 무려 85 초가 걸리며 (희망,기도 하는가?) 100 개가 넘는 문장이있는 모든 Wordid를 찾는 더 빠른 방법이 있습니다.

나는 Select Count Part를 꺼내고 'count (1)'을하는 것을 시도했지만 속도를 높이지는 않았다.

당신이 빌릴 수있는 도움에 감사드립니다. 감사!

도움이 되었습니까?

해결책

count (sentence_id)> 100;

이것에 문제가 있습니다 ... 테이블에는 중복 단어/문장 쌍이 있거나 그렇지 않습니다.

중복 단어/문장 쌍이있는 경우이 코드를 사용하여 정답을 얻어야합니다.

HAVING COUNT(DISTINCT Sentence_ID) > 100

테이블에 중복 단어/문장 쌍이없는 경우 ... Sentence_ids를 계산해서는 안됩니다. 단지 행을 계산해야합니다.

HAVING COUNT(*) > 100

이 경우 인덱스를 만들 수 있습니다. Word_id 만, 최적의 성능을 위해.

다른 팁

아직 하나가 없으면 sentence_id, word_id에서 복합 색인을 만듭니다.

해당 쿼리가 종종 수행되고 테이블이 거의 업데이트되지 않으면 단어 ID와 해당 문장 계수가있는 보조 테이블을 보관할 수 있습니다. 그 이상의 추가 최적화를 생각하기 어렵습니다!

쿼리는 괜찮지 만 더 빠른 결과를 얻으려면 약간의 도움 (색인)이 필요합니다.

당면한 자원이 없거나 SQL에 액세스 할 수는 없지만 메모리에서 당신을 도와 드리겠습니다.

개념적으로, 그 쿼리에 답하는 유일한 방법은 동일한 Word_id를 공유하는 모든 레코드를 계산하는 것입니다. 즉, 쿼리 엔진은 해당 레코드를 찾을 수있는 빠른 방법이 필요합니다. Word_id의 색인이 없으면 데이터베이스가 수행 할 수있는 유일한 일은 한 번에 한 레코드 씩 테이블을 거쳐서 찾은 모든 단일 word_id의 총계를 계속 실행하는 것입니다. 일반적으로 임시 테이블이 필요하며 전체 테이블을 스캔 할 때까지 결과를 발송할 수 없습니다. 안좋다.

Word_id의 색인을 사용하면 여전히 테이블을 통과해야합니다. 당신은 생각할 것입니다 많은 도움이되지 않을 것입니다. 그러나 SQL 엔진은 이제 테이블 끝까지 기다리지 않고 각 Word_id의 카운트를 계산할 수 있습니다. Word_id의 해당 값에 대한 행을 발송할 수 있습니다 (통과하는 경우 where 조항) 또는 행을 버립니다 (그렇지 않은 경우). 이렇게하면 서버에서 메모리로드가 낮아지고 부분 응답이 줄어들고 임시 테이블이 더 이상 필요하지 않습니다. 두 번째 측면은 평행주의입니다. Word_id의 색인을 사용하면 SQL은 작업을 청크로 분할하고 별도의 프로세서 코어를 사용하여 쿼리를 병렬로 실행할 수 있습니다 (하드웨어 기능 및 기존 워크로드에 따라).

그것은 당신의 질문에 도움이 충분할 수 있습니다. 그러나 당신은 다음을 시도해야합니다.

CREATE INDEX someindexname ON sentence_word (word_id)

(T-SQL 구문; 사용중인 SQL 제품을 지정하지 않았습니다)

그것이 충분하지 않거나 전혀 도움이되지 않는다면, 다른 두 가지 해결책이 있습니다.

먼저 SQL을 사용하면 인덱스 된 뷰 및 기타 메커니즘을 사용하여 Count (*)를 사전 컴퓨팅 할 수 있습니다. 나는 세부 사항이없고 (그리고 나는 이것을 자주하지 않습니다). 데이터가 자주 변경되지 않으면 더 빠른 결과를 얻을 수 있지만 복잡성과 약간의 스토리지가 있습니다.

또한 쿼리 결과를 별도의 테이블에 저장하는 것을 고려할 수도 있습니다. 데이터가 변경되지 않거나 정확한 일정으로 변경되지 않은 경우에만 실용적입니다 (예 : 아침 2시에 데이터 새로 고침 중)이 거의 변경되지 않고 몇 시간 동안 완벽한 결과를 얻을 수있는 경우에만 실용적입니다. 주기적인 데이터 새로 고침을 예약해야합니다); 그것은 가난한 사람의 데이터웨어 하우스와 동등한 도덕적입니다.

당신에게 무엇이 효과가 있는지 확인하는 가장 좋은 방법은 쿼리를 실행하고 위의 후보 인덱스 유무에 관계없이 쿼리 계획을 보는 것입니다.

놀랍게도 대규모 데이터 세트에서이를 달성하는 더 빠른 방법이 있습니다.

SELECT totals.word_id, totals.num 
  FROM (SELECT word_id, COUNT(*) AS num FROM sentence_word GROUP BY word_id) AS totals
 WHERE num > 1000;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top