Вопрос об эффективности объединения таблиц - PullRequest
3 голосов
/ 12 мая 2009

При объединении между таблицами (как в примерах ниже), существует ли разница в эффективности между объединением в таблицах или объединением подзапросов, содержащих только необходимые столбцы?

Другими словами, есть ли разница в эффективности между этими двумя таблицами?

SELECT result
  FROM result_tbl
  JOIN test_tbl                    USING (test_id)
  JOIN sample_tbl                  USING (sample_id)
  JOIN (SELECT request_id
          FROM request_tbl
         WHERE request_status='A') USING(request_id)

против

SELECT result
  FROM (SELECT result,  test_id   FROM result_tbl)
  JOIN (SELECT test_id, sample_id FROM test_tbl)   USING(test_id)
  JOIN (SELECT sample_id          FROM sample_tbl) USING(sample_id)
  JOIN (SELECT request_id
          FROM request_tbl
         WHERE request_status='A')                 USING(request_id)

Ответы [ 3 ]

5 голосов
/ 12 мая 2009

Единственный способ узнать наверняка - запустить оба с включенной трассировкой, а затем посмотреть файл трассировки. Но, по всей вероятности, они будут обрабатываться одинаково: оптимизатор объединит все встроенные представления в основной оператор и разработает один и тот же план запросов.

4 голосов
/ 12 мая 2009

Это не имеет значения. Это может быть на самом деле ХОРОШО, так как вы забираете контроль у оптимизатора, который обычно лучше всех знает.

Однако помните, что если вы выполняете JOIN и только включаете столбец из одной из таблиц, то ЧАСТО ДАЛЕЕ лучше переписать его как серию операторов EXISTS - потому что это то, что вы действительно имеете в виду. СОЕДИНЕНИЯ (за некоторыми исключениями) объединят соответствующие строки, что оптимизатору предстоит сделать гораздо больше.

, например

SELECT t1.id1
  FROM table1 t1
 INNER JOIN table2 ON something = something

почти всегда должно быть

SELECT id1
  FROM table1 t1
 WHERE EXISTS( SELECT *
                 FROM table2
                WHERE something = something )

Для простых запросов оптимизатор может свести планы запросов к идентичным. Проверьте это на вашей СУБД.

Также это запах кода и, вероятно, его следует изменить:

JOIN (ВЫБЕРИТЕ request_id FROM request_tbl ГДЕ request_status = 'A')

до

SELECT result
  FROM request
 WHERE EXISTS(...)
   AND request_status = 'A'
2 голосов
/ 25 мая 2009

Без разницы.

Вы можете определить, запустив EXPLAIN PLAN для обоих этих операторов - Oracle знает, что все, что вам нужно, это столбец «результата», поэтому он выполняет только необходимый минимум для получения необходимых данных - вы должны обнаружить, что планы будут тождественны.

Оптимизатор Oracle иногда «материализует» подзапрос (то есть запускает подзапрос и сохраняет результаты в памяти для последующего повторного использования), но это происходит редко и происходит только тогда, когда оптимизатор полагает, что это приведет к повышению производительности; в любом случае Oracle выполнит эту «материализацию» независимо от того, указали вы столбцы в подзапросах или нет.

Очевидно, что если единственное место, в котором хранится столбец «результатов», находится в блоках (вместе с остальными данными), Oracle должен посетить эти блоки - но он будет хранить только соответствующую информацию (столбец «результатов») и другие соответствующие столбцы, например, «test_id») в памяти при обработке запроса.

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