Сравнение производительности в Oracle

#oracle #query-optimization

Вопрос:

Я хотел бы сравнить две инструкции SQL, которые дают один и тот же результат. Например

 SELECT
    id, name,
    (SELECT street || ' ' || town from addresses WHERE addresses.id=customers.addressid) AS address
FROM customers;

--  vs

SELECT
    id, name,
    street || ' ' || town AS address
FROM customers c LEFT JOIN addresses a ON c.id=a.customerid;
 

Здесь я хочу сравнить производительность подзапроса по сравнению с использованием соединения. Я знаю о других преимуществах и недостатках подзапросов и объединений, но меня больше интересует сравнение их производительности.

Как я могу сравнить производительность? Есть ли какая-то проверка времени?

Комментарии:

1. Эти два запроса делают разные вещи. Если вы хотите сравнить их, вам нужно использовать внешнее соединение во втором запросе ( LEFT JOIN addresses a on ... ). Я не удивлюсь, если вы увидите идентичные планы выполнения для бота, то

2. @a_horse_with_no_name Хорошая мысль. Я добавлю это в пример. На самом деле меня интересовали не эти конкретные запросы, а то, как их сравнивать. Однако я, безусловно, должен убедиться, что они делают то же самое.

Ответ №1:

Есть ли какая-то проверка времени?

Да, в SQL*Plus сделайте это как

 SQL> set timing on
 

а затем выполните запросы, каждый из них несколько раз (чтобы избежать проблем с кэшированием), и сравните время, необходимое для выполнения каждого запроса. Обратите внимание, что в небольших наборах данных вы не заметите никакой разницы, так что — что бы вы ни использовали, все будет в порядке.

 SQL> select e.deptno, (select d.dname from dept d where d.deptno = e.deptno) dname, e.ename
  2  from emp e
  3  where e.deptno = 20;

    DEPTNO DNAME          ENAME
---------- -------------- ----------
        20 RESEARCH       SMITH
        20 RESEARCH       JONES
        20 RESEARCH       SCOTT
        20 RESEARCH       ADAMS
        20 RESEARCH       FORD

Elapsed: 00:00:00.04
SQL> select e.deptno, d.dname, e.ename
  2  from emp e join dept d on e.deptno = d.deptno
  3  where e.deptno = 20;

    DEPTNO DNAME          ENAME
---------- -------------- ----------
        20 RESEARCH       SMITH
        20 RESEARCH       JONES
        20 RESEARCH       SCOTT
        20 RESEARCH       ADAMS
        20 RESEARCH       FORD

Elapsed: 00:00:00.03
SQL>
 

Кроме этого, вы сравнивали свои планы? Собирали ли вы статистику по таблицам и индексам (и делаете ли это регулярно)? Существуют ли какие-либо индексы (скорее всего, они должны быть на столбцах, используемых в соединениях)?