SQL: улучшение скорости - загроможденный объединенный запрос - PullRequest
0 голосов
/ 17 февраля 2011
SELECT * FROM (
    SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
    FROM         current_tbl a
    INNER JOIN   import_tbl  b 
                 ON ( a.user_id = b.user_id )
    UNION
    SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
    FROM         current_tbl a
    INNER JOIN   import_tbl  b 
                 ON (   lower(a.f_name)=lower(b.f_name) 
                    AND lower(a.l_name)=lower(b.l_name) ) 
) foo
--
UNION
--
SELECT a.user_id , a.f_name , a.l_name , '' , '' , '' 
FROM   current_tbl a
WHERE  a.user_id NOT IN (
   select user_id from(
      SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
      FROM         current_tbl a
      INNER JOIN   import_tbl  b 
                   ON ( a.user_id = b.user_id )
      UNION
      SELECT       a.user_id, a.f_name, a.l_name, b.user_id, b.f_name, b.l_name
      FROM         current_tbl a
      INNER JOIN   import_tbl  b 
                   ON (   lower(a.f_name)=lower(b.f_name) 
                      AND lower(a.l_name)=lower(b.l_name) ) 
   ) bar
)
ORDER BY user_id

Пример заполнения таблицы :

current_tbl:

-------------------------------
user_id  |  f_name  |  l_name
---------+----------+----------
  A1     |  Adam    |  Acorn
  A2     |  Beth    |  Berry
  A3     |  Calv    |  Chard
         |          |

import_tbl:

-------------------------------
user_id  |  f_name  |  l_name
---------+----------+----------
  A1     |  Adam    |  Acorn
  A2     |  Beth    |  Butcher  <- last_name different
         |          |

Ожидаемый результат:

-----------------------------------------------------------------------
user_id1  |  f_name1  |  l_name1  |  user_id2  |  f_name2  |  l_name2
----------+-----------+-----------+------------+-----------+-----------
   A1     |  Adam     |  Acorn    |     A1     |  Adam     |  Acorn       
   A2     |  Beth     |  Berry    |     A2     |  Beth     |  Butcher
   A3     |  Calv     |  Chard    |            |           |           

Использование этого метода избавляет от условий, в которых строка будет:

   A2     |  Beth     |  Berry    |     A2     |  Beth     |  Butcher

Но он сохраняет ряд A3


Надеюсь, это имеет смысл, и я не слишком упрощал это. Это продолжение вопроса из моего другого вопроса . Последовательность этих улучшений снизила запрос с ~ 32000 мс до того места, где он сейчас составляет ~ 1200 мс - значительное улучшение.

Полагаю, что я могу оптимизировать, используя UNION ALL в подзапросе и, конечно, обычную оптимизацию индекса, но я ищу лучшую оптимизацию SQL. К вашему сведению, этот конкретный случай относится к PostgreSQL.

1 Ответ

1 голос
/ 17 февраля 2011

Я думаю, что это почти идентично, намного меньше и кажется чтобы иметь больше смысла для меня. Мой первый инстинкт это должен работать намного быстрее, хотя может быть и не лучшим:)

SELECT       a.user_id, a.f_name, a.l_name, 
             COALESCE(b.user_id, ''), COALESCE(b.f_name, ''), COALESCE(b.l_name, '')
FROM         current_tbl a
LEFT OUTER JOIN import_tbl  b ON
   ( a.user_id = b.user_id ) OR
   ( lower(a.f_name)=lower(b.f_name) 
     AND lower(a.l_name)=lower(b.l_name) ) 

EDIT: Смейтесь над собой, чтобы более или менее рекомендовать вам отменить предыдущие изменения Вы сделали в своем первоначальном вопросе.

...