HAVING = bad, WHERE = good!

A cláusula WHERE é usada para filtrar linhas, enquando a cláusula HAVING é usada para filtrar grupos de linhas. O filtro de grupos é feito depois do agrupamento – e um agrupamento pode ser bem custoso para o banco. Por isso, sempre que possível, devemos primeiro filtrar as linhas usando um WHERE. Assim evitamos o tempo gasto para agrupar as linhas filtradas. Exemplos abaixo

Ruim (usando HAVING)

SQL> select department_id, avg(salary)
  2  from employees
  3  group by department_id
  4  having department_id in (40, 60, 110);

DEPARTMENT_ID AVG(SALARY)
------------- -----------
          110       10154
           40        6500
           60        5760

Bom (usando WHERE)

SQL> select department_id, avg(salary)
 2  from employees
 3  WHERE department_id in (40, 60, 110)
 4  GROUP BY department_id;

DEPARTMENT_ID AVG(SALARY)
 ------------- -----------
 40        6500
 60        5760
 110       10154

UNION = bad, UNION ALL = good!

Ao recuperar registros semelhantes de duas tabelas, UNION é usado para remover as linhas duplicadas – enquanto UNION ALL retorna todas as linhas, incluindo as duplicadas. Avalie a possibilidade de usar UNION ALL ao invés de UNION. Apesar de retornar mais linhas, é menos custoso, pois não tem o trabalho de remover as linhas duplicadas.

Ruim (usando UNION):

SQL> SELECT region_id, region_name
  2  FROM regions
  3  UNION
  4  SELECT region_id, region_name
  5  FROM regions2;

 REGION_ID REGION_NAME
---------- -------------------------
         1 Europe
         2 Americas
         3 Asia
         4 Middle East and Africa

Bom (usando UNION ALL):

SQL> SELECT region_id, region_name
  2  FROM regions
  3  UNION ALL
  4  SELECT region_id, region_name
  5  FROM regions2;

 REGION_ID REGION_NAME
---------- -------------------------
         1 Europe
         2 Americas
         3 Asia
         4 Middle East and Africa
         1 Europe
         2 Americas
         3 Asia
         4 Middle East and Africa