дублирующиеся данные или лучшая производительность? - PullRequest
0 голосов
/ 02 марта 2011

Нам нужно отображать название нашего продукта на разных языках, но только некоторые из них имеют названия на разных языках, чем английский.Когда мы запрашиваем продукты с определенным языком, мы хотим показать имя по умолчанию на английском языке, если имя определенного языка отсутствует.

Чтобы получить лучшую производительность запросов, мы должны заполнить английское имя по умолчанию в таблице имен продуктов, зависящих от языка (languageid + productid - это первичный ключ), когда имя для определенного языка отсутствует.Он сделал много повторяющихся имен в этой языковой таблице, и немного сложно обновить эту таблицу, когда английское имя по умолчанию изменилось.

В настоящее время у нас около 300 000 продуктов с 30 языками и более 8 000 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)

Ответы [ 3 ]

2 голосов
/ 02 марта 2011

Вы проверяли ЛЕВУЮ РЕЙТИНГ и ISNULL?или это только предположение?Учитывая, что вы перемещаете много данных, я бы сказал, что дополнительная языковая строка будет намного быстрее, если у вас не будет действительно плохой индексации

SELECT
   ...,
   ISNULL(L.languageproductName, P.productname)
FROM
   Product P
   LEFT JOIN
   LangaugeStuff L ON P.productID = L.productID AND L.languageID = @Mylanguage
1 голос
/ 02 марта 2011

Я не уверен, выполнимо ли это для вашей конкретной ситуации, но почему бы не позволить слою интерфейса пользовательского интерфейса или прикладному уровню обрабатывать перевод по общему шаблону локализации?

0 голосов
/ 02 марта 2011

Если в этой языковой записи нет названия вашего продукта, введите 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 пропускает ноль и вводит название продукта по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...