Как уменьшить количество запросов в нормализованной базе данных? - PullRequest
0 голосов
/ 25 ноября 2011

Представьте себе стол для статей. В дополнение к основному запросу:

SELECT * From articles WHERE article_id='$id'

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

SELECT * FROM users WHERE user_id='$author_id' // Taken from main query

SELECT tags.tag 
FROM tags 
  INNER JOIN tag_map 
    ON tags.tag_id=tag_map.tag_id 
WHERE article_id='$id'

и еще несколько запросов к категориям, аналогичным статьям и т. Д.

Вопрос 1: Это лучший способ выполнять эти запросы отдельно с PHP и обрабатывать данные результаты, или есть способ объединить их?

Вопрос 2: В отсутствие отношений many-to-many (например, один тег, категория, автор для каждой статьи, идентифицированной по tag_id, category_id, author_id); Что было лучше (быстрее), чтобы получить данные из таблиц.

Ответы [ 3 ]

3 голосов
/ 25 ноября 2011

Если бы все отношения были один-много, то вы могли бы довольно легко получить все эти данные в одном запросе, например

SELECT
    [fields required]
FROM
    articles a
    INNER JOIN
        users u ON a.author_id=u.user_id
    INNER JOIN 
        tag_map tm ON tm.article_id=a.article_id
    INNER JOIN
        tags t t.tag_id=tm.tag_id
WHERE
    a.article_id='$id'

Это обычно было бы быстрее, чем три запроса в отдельности, так как ваши таблицы проиндексированыправильно, так как MySQL создан для этого!Это сэкономит на двух поездках в базу данных и связанных с этим издержках.

1 голос
/ 25 ноября 2011

Вы можете объединить пользователя в первом запросе:

SELECT a.*, u.*
FROM   articles a
JOIN   users u ON u.user_id = a.author_id
WHERE  a.article_id='$id';

Вы можете сделать то же самое с тегами, но это приведет к некоторой избыточности в ответе, посколькуочевидно, несколько тегов на статью.Может или не может быть полезным.

В отсутствие отношений many-to-many это сделало бы работу одним махом и было бы лучше в любом случае:

SELECT *
FROM   users u
JOIN   articles a ON a.author_id = u.user_id
JOIN   tag t      USING (tag_id)  -- I assume a column articles.tag_id in this case
WHERE  a.article_id = '$id';

Вы можетехочу быть более избирательным к каким столбцам возвращать.Если теги не гарантированы, существуют вторые JOIN a LEFT JOIN.

0 голосов
/ 25 ноября 2011

Вы можете добавить надлежащим образом денормализованное представление к вашим нормализованным таблицам, где каждая запись содержит все необходимые данные. Или вы можете инкапсулировать вызовы SQL в хранимых процедурах и вызывать эти процессы из своего кода, что должно повысить производительность. Докажи и то и другое и получи твердые цифры; всегда лучше принимать решения, основанные на доказательствах, а не на идеях. :)

...