Как оптимизировать этот SQL-запрос? - PullRequest
1 голос
/ 12 октября 2009

У меня есть база данных с вопросами и ответами, которые переводятся на все языки, которые использует сайт Но когда вопрос еще не переведен, я хочу показать этот вопрос на английском языке. Так что поведение, похожее на gettext.

Мой текущий SQL-запрос выглядит так:

SELECT * FROM questions_view WHERE `language` = "de" AND `#parent` IS NULL
UNION 
SELECT * FROM questions_view WHERE `language` = "en" AND `#parent` IS NULL 
    AND id NOT IN (SELECT id 
                   FROM questions_view 
                   WHERE `language` = "de")

Но я чувствую, что это не оптимальный способ сделать это. Любые советы?

Ответы [ 5 ]

2 голосов
/ 12 октября 2009

Это:

SELECT  qi.*
FROM    (
        SELECT  DISTINCT id
        FROM    questions_view
        ) qd
JOIN    questions_view qi
ON      qi.id = qd.id
        AND qi.language =
        COALESCE(
        (
        SELECT  language
        FROM    questions_view qn
        WHERE   parent IS NULL
                AND language = 'de'
                AND qn.id = qd.id
        ),
        (
        SELECT  language
        FROM    questions_view qn
        WHERE   parent IS NULL
                AND language = 'en'
                AND qn.id = qd.id
        )
        )

или это:

SELECT  COALESCE(qde.question_text, qen.question_text)
FROM    (
        SELECT  DISTINCT id
        FROM    questions_view
        ) qd
LEFT JOIN
        questions_view qde
ON      qde.id = qd.id
        AND qde.language = 'de'
LEFT JOIN
        questions_view qen
ON      qen.id = qd.id
        AND qen.language = 'en'

Что, если эти запросы лучше, зависит от вашей системы баз данных и от того, сколько вопросов в вашей базе данных переведено.

См. Эту серию статей в моем блоге для более подробной информации:

1 голос
/ 12 октября 2009

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

например

Select col1, col2, col3, col_etc from questions_view where 
language in ('de','en') and #parent is null
1 голос
/ 12 октября 2009

Возможно удалить 1 поездку в БД, удалив существующее и просто взяв первый доступный ответ, например,

Select Top 1 *
FROM
(
    select 1 as myRank, * from questions_view where `language` = "de" and `#parent` is null
    union 
    select 2 as myRank, * from questions_view where `language` = "en" and `#parent` is null 
) A
Order By myRank asc
1 голос
/ 12 октября 2009

Не знаю, прав ли я, но этого недостаточно

select * from questions_view where language in ('de','en') and #parent is null
1 голос
/ 12 октября 2009

Hm. Я не могу думать ни о каком другом решении. Вы можете установить language на null, если вопрос еще не переведен, что позволит вам изменить его следующим образом:

select * from questions_view where `language` = "de" and `#parent` is null
union 
select * from questions_view where `language` is null and `#parent` is null 

OTOH может помочь сначала добавить переведенные вопросы во временную таблицу, а затем выполнить "не существует на немецком" -проверьте как

and not exists (select 1 from temp_translated t where t.id = id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...