2011-03-02 5 views
0

Google은 제품 이름을 다른 언어로 표시해야하지만 일부 언어 만 영어와 다른 언어로 이름을 지정합니다. 특정 언어로 제품을 쿼리 할 때 특정 언어 이름이없는 경우 기본 이름을 영어로 표시하려고합니다.데이터가 중복되거나 성능이 향상 되었습니까?

더 나은 쿼리 성능을 얻으려면 특정 언어의 이름이 누락되면 언어 별 제품 이름 테이블 (languageid + productid가 기본 키)에 기본 영어 이름을 입력해야합니다. 이 언어에 의존하는 테이블에 중복 된 이름이 많이 생겼습니다. 기본 영어 이름이 변경되면이 테이블을 업데이트하기가 다소 어려워졌습니다.

현재이 테이블에는 약 30 개 언어와 8,000,000 개 이상의 행이있는 약 300,000 개의 제품이 있으며, 적어도 90 % 이상의 데이터가 중복되어 있으며 기본 영어 이름으로 채 웁니다. 그러나 쿼리에서 왼쪽 조인과 isnull 체크를 사용하면 쿼리 성능이 훨씬 느려집니다.

누가 복제 데이터를 채우고 더 나은 쿼리 성능을 피할 수있는 더 나은 데이터베이스 디자인을 추천 할 수 있습니까?

내가 중복 데이터를 방지하기 위해 쿼리 아래 시도하지만, 성능이 최악의 비트를했다

Table1 (about 300,000 rows) 
ProductId | Country  | Currency | others fields 
------------|----------------|-----------|--------------- 
Product A | US    | USD  | ... 
Product B | GB    | GBP  | ... 

Table2 (about 9,000,000 rows) 
LanguageId | ProductId  | Product Name 
------------|----------------|-------------------------- 
English  | Product A  | Product A Name 
English  | Product B  | Product B Name 
German  | Product A  | Produkt A Name 
German  | Product B  | Product B Name (it's filled by English name) 

아래와 같이 현재의 테이블 스키마.

SELECT 
    A.ProductId, 
    A.Country, 
    ISNULL(B1.ProductName, B2.ProductName) as ProductName 
FROM 
    Table1 A (NOLOCK) 
    LEFT JOIN Table2 B1 (NOLOCK) on A.ProductId = B1.ProductId 
    LEFT JOIN Table2 B2 (NOLOCK) on A.ProductId = B2.ProductId and B2.LanguageId = 'ENGLISH' 
WHERE 
    B1.LanguageId = 'German' 
ORDER BY 
    ISNULL(B1.ProductName, B2.ProductName) 
+0

게시글에 현재 테이블 스키마를 넣을 수 있습니까? –

답변

1

특정 상황에서 가능할 지 모르겠지만 UI 인터페이스 레이어 또는 응용 프로그램 레이어가 일반적인 지역화 패턴을 통해 번역을 처리하게하는 이유는 무엇입니까?

+0

제품 이름 필드별로 정렬해야하기 때문에 UI 레이어에서 현지화가 어렵습니다. – CodeRhino

+0

@CodeRhino, 유효한 우려 사항. 하지만 여전히 현지화가 적용된 응용 프로그램 계층에서 가능할 수 있습니까? –

+0

페이지에서 특정 제품을 보여주고 싶을 때 응용 프로그램 계층에서 현지화를 처리하는 것이 쉽습니다. 그러나 30 만 개가 넘는 제품을 검색하여 페이징하고 결과를 표시하고 제품 이름별로 정렬하려면 어떻게해야합니까? – CodeRhino

0

해당 언어 레코드에 제품 이름이 없으면 해당 필드에 NULL을 입력하십시오. 쿼리를 수행 할 때 COALESCE을 사용하여 NULL을 영어 제품 이름으로 바꿉니다.

SELECT COALESCE(l.ProductName, 'Product Name') 
FROM Language l 

내 제안 된 설계는 다음과 같이 보일 것이다 : 스페인어 이후

Language | ProductName | TitleMenu 
---------------------------------- 
English | Widgetizer | Title 
French | La Widgette | La Title 
Spanish |    | El Title 

NULL 항목이는 COALESCE는 널 (null)을 건너 뛰고 기본 제품 이름에 넣습니다.

+0

그래서 두 개의 열을 제안하고 중복 된 영문 이름을 유지 하시겠습니까? – gbn

2

LEFT JOIN과 ISNULL을 테스트 해 보셨습니까? 아니면 그냥 추측입니까? 많은 데이터가 바뀌고있는 상황에서 잘못된 언어 색인을 사용하지 않는 한 선택적인 언어 행이 훨씬 빠르다는 것을 알고 싶습니다.

SELECT 
    ..., 
    ISNULL(L.languageproductName, P.productname) 
FROM 
    Product P 
    LEFT JOIN 
    LangaugeStuff L ON P.productID = L.productID AND L.languageID = @Mylanguage 
+0

내 쿼리에서 LEFT JOIN 및 ISNULL을 시도했습니다. 우리는 또한 제품 이름으로 데이터를 정렬해야하기 때문에. 그것은 훨씬 느립니다. – CodeRhino

관련 문제