Использовать таблицы сопоставления JOIN лучше, чем несколько полей в одной таблице? - PullRequest
2 голосов
/ 09 февраля 2011

У меня есть таблица из примерно 360 000 записей, и здесь выполняется запрос по двум индексированным полям:

SELECT COUNT(*)
FROM emails
WHERE
department_id IN(1,2,3,4)
AND category_id IN (5,6,7,8)

(Time: 0.9624802)

           id: 1
  select_type: SIMPLE
        table: emails
         type: range
possible_keys: emails_department_id_idx,emails_category_id_idx
          key: emails_category_id_idx
      key_len: 5
          ref: NULL
         rows: 54018
        Extra: Using where

Таким образом, там используется только один индекс.(Я могу заставить слияние индексов работать при использовании более простых сравнений или критериев диапазона, но мне нужно выполнить подобные проверки со списком идентификаторов).

Здесь я создал две новые таблицы для сопоставления этой взаимосвязи, ииспользуя JOIN'ы, я воспроизвел те же результаты:

SELECT COUNT(*)
FROM emails
LEFT JOIN email_to_department ON (email_to_department.email_id = emails.id AND email_to_department.department_id IN (1,2,3,4))
LEFT JOIN email_to_category ON (email_to_category.email_id = emails.id AND email_to_category.category_id IN (5,6,7,8))
WHERE
email_to_department.department_id IS NOT NULL
AND email_to_category.category_id IS NOT NULL

(Time: 0.5217777)

*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: email_to_category
         type: range
possible_keys: PRIMARY,category_id
          key: category_id
      key_len: 4
      ref: NULL
     rows: 61282
    Extra: Using where; Using index
*************************** 2. row ***************************
           id: 1
  select_type: SIMPLE
        table: email_to_department
         type: ref
possible_keys: PRIMARY,department_id
          key: PRIMARY
      key_len: 4
          ref: testdb.email_to_category.email_id
         rows: 1
        Extra: Using where; Using index
*************************** 3. row ***************************
           id: 1
  select_type: SIMPLE
        table: emails
         type: eq_ref
possible_keys: PRIMARY
          key: PRIMARY
      key_len: 4
          ref: testdb.email_to_category.email_id
         rows: 1
        Extra: Using index
3 rows in set (0.38 sec)

Таким образом, каждый запрос теперь использует индекс и обрезает почти половину времени ожидания.Это плохой дизайн?Должен ли я написать остальные эти отношения таким же образом?

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

Выполнение простого запроса только по одному индексируемому полю, конечно, очень и очень быстро:

SELECT COUNT(*)
FROM emails
WHERE department_id IN(1,2,3,4)

Есть ли еще какая-нибудь стратегия, которую я мог бы использовать для ускорения подобных запросов?Существуют и другие свойства, которые также необходимо фильтровать и в разных комбинациях, поэтому создание многостолбечных индексов на самом деле не поможет.

Ответы [ 2 ]

1 голос
/ 25 июня 2012

Это действительно вопрос о нормализации базы данных. Вы можете искать информацию по этой теме во многих местах.

Базовый ответ Так как по этому поводу имеется огромная литература, и есть много различий, я просто укажу, что это сводится к компромиссам; Скорость по сравнению с требованиями к хранилищу или простота использования по сравнению с дублированием данных. Возможно, вы захотите понять, что такое нормализация, чтобы понять, почему вы хотите или не хотите этого делать.

Дальнейшее чтение Это глубокая тема, вы можете захотеть узнать больше - по этим вопросам существуют сотни книг и тысячи научных статей. Например, посмотрите на этот предыдущий вопрос SO о проектировании базы данных: Дизайн базы данных: одна огромная таблица или отдельные таблицы? , или эта: Проектирование базы данных впервые: я перерабатываю? или Основы нормализации базы данных на About.com.

0 голосов
/ 24 февраля 2011

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

...