Ускорение внутренних соединений между большим столом и маленьким столом - PullRequest
30 голосов
/ 13 февраля 2010

Это может быть глупый вопрос, но он может пролить некоторый свет на то, как объединения работают внутри.

Допустим, у меня есть большая таблица L и маленькая таблица S (100 000 строк против 100 строк).

Будет ли разница в скорости между следующими двумя вариантами?:

OPTION 1:                 OPTION 2:
---------                 ---------
SELECT *                  SELECT *
FROM L INNER JOIN S       FROM S INNER JOIN L
ON L.id = S.id;           ON L.id = S.id;

Обратите внимание, что единственное отличие - это порядок объединения таблиц.

Я понимаю, что производительность может отличаться для разных языков SQL. Если так, то как бы сравнил MySQL с Access?

Ответы [ 2 ]

19 голосов
/ 13 февраля 2010

Нет, порядок не имеет значения.

Почти во всех СУБД (таких как MS Access, MySQL, SQL Server, ORACLE и т. Д.) Используется оптимизатор на основе затрат на основе статистики столбцов. В большинстве ситуаций оптимизатор выберет правильный план. В приведенном вами примере порядок не будет иметь значения (если статистика актуальна).

Чтобы решить, какую стратегию запроса использовать, оптимизатор Jet Engine использует статистика. Следующие факторы некоторые из факторов, которые эти статистика основана на:

  • Количество записей в таблице
  • Количество страниц данных в таблице
  • Расположение таблицы
  • Есть ли индексы
  • Насколько уникальны индексы

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

На основании этой статистики Оптимизатор затем выбирает лучший внутренняя стратегия запроса для решения с конкретным запросом.

Статистика обновляется всякий раз, когда запрос скомпилирован. Запрос помечен для компиляции при сохранении любого изменения в запросе (или его базовые таблицы) и когда база данных сжата Если запрос помечены для компиляции, компиляция и происходит обновление статистики при следующем запуске запроса. Компиляция обычно занимает от одного секунды до четырех секунд.

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

Ref .

Может представлять интерес: ACC: как оптимизировать запросы в Microsoft Access 2.0, Microsoft Access 95 и Microsoft Access 97

Часто задаваемые вопросы о производительности Microsoft Access от Тони Тоевса стоит прочитать.

2 голосов
/ 13 февраля 2010

Я знаю, что Oracle нет в вашем списке, но я думаю, что большинство современных баз данных будут вести себя таким образом.

Как видно из следующего плана выполнения, между этими двумя утверждениями нет никакой разницы.

Это полный доступ к каждой из двух таблиц (в моем случае индекса нет), а затем HASH JOIN.Поскольку вам нужно все из обеих таблиц, обе таблицы должны быть прочитаны и объединены, последовательность не оказывает влияния.

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |   100 |   700 |    42  (12)| 00:00:01 |
|*  1 |  HASH JOIN         |      |   100 |   700 |    42  (12)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| S    |   100 |   300 |     2   (0)| 00:00:01 |
|   3 |   TABLE ACCESS FULL| L    |   100K|   390K|    38   (8)| 00:00:01 |
---------------------------------------------------------------------------
...