2009-07-20 10 views
1

소매점 체인을위한 응용 프로그램을 작성한다고 가정 해 봅시다. 따라서 핵심 비즈니스 오브젝트 및 많은 지원 오브젝트로서 '상점'을 정의하도록 오브젝트 모델을 설계하십시오. 의 다음과 같은 '스토어'보이는 가정 해 봅시다 :언제 '안'으로되어 있지 않습니까?

class Store implements Validatable{ 
int storeNo; 
int storeName; 
... etc.... 
} 

그래서, 당신의 클라이언트 응용 프로그램에 엑셀 시트에서 저장 일정을 가져올 수 있고 당신이 그들을에 검증하는 일련의를 실행해야한다는 것을 알려줍니다. 예를 들어, 'StoreIsInSameCountry', 'StoreIsValid'... 등. 따라서 모든 비즈니스 조건을 확인하기위한 규칙 인터페이스를 설계 할 수 있습니다. 다음과 같은 내용 :

interface Rule T extends Validatable> { 
public Error check(T value) throws Exception; 
} 

여기에 질문이 있습니다. 이 엑셀 시트에서 2000 개의 스토어를 업로드 중입니다. 그래서, 나는 여러 번 상점을 위해 정의 된 각 규칙을 실행하게 될 것입니다. 데이터베이스에 4 개의 규칙 = 8000 검색어, 즉 연결 풀에 16000 회의 조회가있을 경우. 난 그냥 가게가 존재하는지 여부를 확인해야합니다 간단한 체크를 들어, 쿼리는 다음과 같습니다 내가 얻을 것

SELECT STORE_ATTRIB1, STORE_ATTRIB2... from STORE where STORE_ID = ? 

그런 식으로 내 '스토어'개체를 가져옵니다. 데이터베이스에서 아무것도 얻지 못하면 해당 저장소가 존재하지 않습니다. 이렇게 간단한 검사를 위해 2000 개의 상점에서 데이터베이스를 2000 번 사용해야했습니다.

또한, 나는 다만 수 :

SELECT STORE_ATTRIB1, STORE_ATTRIB2... from STORE where STORE_ID in (1,2,3.....) 

이 쿼리는 실제로 2000 배 위를하는 것보다 훨씬 빠르게 반환합니다. 그러나 단일 저장소에 대해서만 규칙을 실행할 수 있다는 설계와 잘 어울리지 않습니다.

나는 IN을 사용하는 것이 권장 방법이 아니라는 것을 알고 있습니다. 그래서 내가 어떻게해야한다고 생각하니? 내가 여기에 IN을 사용해야한다면,이 시나리오에서 더 나은 성능을 제공합니까? 또는 디자인을 변경해야합니까?

신발을 신고 있다면 무엇을하겠습니까? 그리고 가장 좋은 방법은 무엇입니까?

답변

0

클라이언트가 가져 오기를 실행하는 빈도, 솔루션을 구현하는 데 얼마나 오래 걸릴지, 시간당 시간당 비용이 얼마나되는지를 비즈니스 문제로 생각합니다.

가끔씩 실행되는 경우 성능이 약간 떨어지는 것은 제 의견으로는 좋습니다. 특히 깨끗한 코드를 사용하여 작업을 빠르게 완료 할 수 있다면 더욱 그렇습니다.

1
SELECT store_id FROM store WHERE store_active = 1 

또는

SELECT store_id FROM store 

는 단일 쿼리 당신에게 모든 활성 매장을 말할 것이다. 현재 알고있는 상점에서 다른 테스트를 수행 할 수 있으며 1,999 개의 히트 수를 데이터베이스에 저장했습니다.

비교적 논쟁의 여지가없는 데이터베이스 액세스가 있고 모든 작업을 수행하는 데 걸리는 시간 제한이없는 경우 연결 풀에 대한 반복적 인 액세스를 걱정할 필요가 없습니다. 그것은 결국 그것을 위해 설계된 것입니다!

+1

당신이 말하는 것에 대해, 내가 어딘가에 그 결과 셋을 캐시한다면 그것은 의미가 있습니다. 위에서 언급 한 접근법을 사용하여 한 번에 하나의 저장소를 확인해야하고 결과 집합을 캐싱하지 않으면 데이터베이스에 대한 1999 번의 히트를 어떻게 줄일 수 있는지 보지 못합니다. – Jay

+0

쿼리를 실행하고 결과를 목록 에 저장합니다. 그것은 당신이 처음 시험입니다. 목록의 크기가 예상되는 상점 수와 일치합니까? 그런 다음 각 Integer를 JDBC 쿼리의 저장소 ID로 사용하여 상점에서 다른 테스트를 실행하는 목록을 반복 할 수 있습니다. – banjollity

+0

위의 쿼리를 IN (select ...) 내부에서 하위 쿼리로 사용할 수 있습니다. 캐싱이 전혀 사용되지 않았습니다. – txwikinger

2

그런 식으로 데이터베이스에서 'Store'개체를 가져올 수 있습니다. 데이터베이스에서 아무것도 얻지 못하면 해당 저장소가 존재하지 않습니다. 이렇게 간단한 검사를 위해 2000 개의 상점에서 데이터베이스를 2000 번 사용해야했습니다.

이 아닙니다.

같이, 당신의 가치와 JOIN이 테이블과 테이블을 작성 임시 테이블을 만듭니다

SELECT STORE_ATTRIB1, STORE_ATTRIB2... 
FROM temptable tt 
JOIN STORE s 
ON  s.STORE_ID = t.id 

나이 :

SELECT STORE_ATTRIB1, STORE_ATTRIB2... 
FROM STORE s 
WHERE s.STORE_ID IN 
     (
     SELECT id 
     FROM temptable tt 
     ) 

을 내가 IN을 사용하여 알고하는 것은 권장하지 않습니다 방법론. 그래서 내가 어떻게해야한다고 생각하니? 내가 여기에 IN을 사용해야한다면,이 시나리오에서 더 나은 성능을 제공합니까? 또는 디자인을 변경해야합니까?

IN 필터가 중복됩니다.

목록의 각 중복 값에 적합한 각 행을 선택하려면 JOIN을 사용하십시오.

IN은 결코 "제안되지 않은 방법론"이 아닙니다.

실제로 일부 데이터베이스가 IN 쿼리를 비효율적으로 지원하지 않는 경우가 있었기 때문에 민속의 지혜가 여전히 그것을 사용하는 것에 대한 조언이었습니다.

하지만 당신의 store_id 경우

가 제대로 인덱싱, 주요 데이터베이스의 모든 현대적인 버전 (즉, SQL Server, MySQLPostgreSQL Oracle입니다) 효율적인를 사용합니다 (그리고 아마 그것이처럼 보이는 PRIMARY KEY의 경우입니다) 이 쿼리를 수행 할 계획입니다.

SQL Server의 성능 자세한 내용은 내 블로그에서이 문서를 참조하십시오 적절하게 설계된 데이터베이스에
  • IN vs. JOIN vs. EXISTS
    • , 그이, 유효성 검사 규칙도 설정을 기반으로합니다.

      I. e. temptable에 대한 쿼리로 유효성 검사 규칙을 구현합니다.

      그러나 레거시 규칙을 지원하려면 유인 할 행 단위의 행에서 값을 선택하고 규칙을 적용하고 유효성 검사를 통과하지 못한 값을 삭제할 수 있습니다.

    관련 문제