PostrgreSQL에서 힌트를 사용할 때는, 힌트 전에 어떠한 주석도 있어서는 안된다. 또한 힌트는 SELECT 키워드보다 위에 위치하거나 SELECT 키워드 바로 다음에 위치해야 한다.

아래 세 개 SQL은 힌트가 제대로 작동한다. 힌트가 다른 어떠한 주석보다 위에 존재해야 한다. 시스템을 개발하다 보면, SQL마다 SQL을 구분할 수 있는 XML Mapper SQL ID를 주석 형태로 넣는 것이 좋다. PostgreSQL에서는 다음과 같이 XML Mapper SQL ID가 힌트보다 아래에 위치해야 한다. 오라클에서 PG로 전환할 때 주의해야 할 사항이라 할 수 있다.

SELECT  /*+ NestLoop(t1 t2) Leading((t1 t2)) */
        -- xml_mapper_sql_id: select_mbr_big_group_01
        t1.mbr_id ,MAX(t1.nick_nm) nick_nm ,COUNT(*) entry_cnt
FROM    ms_mbr_big t1
        INNER JOIN tr_event_entry_big t2 ON (t2.mbr_id = t1.mbr_id)
WHERE   t1.mbr_gd = 'GOLD'
AND     t2.entry_dtm >= TO_DATE('20230114','YYYYMMDD')
AND     t2.entry_dtm <  TO_DATE('20230115','YYYYMMDD')
GROUP BY t1.mbr_id;

/*+ NestLoop(t1 t2) Leading((t1 t2)) */
SELECT  -- xml_mapper_sql_id: select_mbr_big_group_01
        t1.mbr_id ,MAX(t1.nick_nm) nick_nm ,COUNT(*) entry_cnt
FROM    ms_mbr_big t1
        INNER JOIN tr_event_entry_big t2 ON (t2.mbr_id = t1.mbr_id)
WHERE   t1.mbr_gd = 'GOLD'
AND     t2.entry_dtm >= TO_DATE('20230114','YYYYMMDD')
AND     t2.entry_dtm <  TO_DATE('20230115','YYYYMMDD')
GROUP BY t1.mbr_id;

/*+ NestLoop(t1 t2) Leading((t1 t2)) */
-- xml_mapper_sql_id: select_mbr_big_group_01
SELECT  t1.mbr_id ,MAX(t1.nick_nm) nick_nm ,COUNT(*) entry_cnt
FROM    ms_mbr_big t1
        INNER JOIN tr_event_entry_big t2 ON (t2.mbr_id = t1.mbr_id)
WHERE   t1.mbr_gd = 'GOLD'
AND     t2.entry_dtm >= TO_DATE('20230114','YYYYMMDD')
AND     t2.entry_dtm <  TO_DATE('20230115','YYYYMMDD')
GROUP BY t1.mbr_id;

아래는 힌트가 작동하지 않는 케이스다. 힌트가 아닌 주석이 힌트보다 위에 있는 케이스다. 지난 교육에서 열강 수강생 분께서 발견해주신 케이스다.

SELECT  -- xml_mapper_sql_id: select_mbr_big_group_01
        /*+ NestLoop(t1 t2) Leading((t1 t2)) */
        t1.mbr_id ,MAX(t1.nick_nm) nick_nm ,COUNT(*) entry_cnt
FROM    ms_mbr_big t1
        INNER JOIN tr_event_entry_big t2 ON (t2.mbr_id = t1.mbr_id)
WHERE   t1.mbr_gd = 'GOLD'
AND     t2.entry_dtm >= TO_DATE('20230114','YYYYMMDD')
AND     t2.entry_dtm <  TO_DATE('20230115','YYYYMMDD')
GROUP BY t1.mbr_id;

-- xml_mapper_sql_id: select_mbr_big_group_01
/*+ NestLoop(t1 t2) Leading((t1 t2)) */
SELECT  t1.mbr_id ,MAX(t1.nick_nm) nick_nm ,COUNT(*) entry_cnt
FROM    ms_mbr_big t1
        INNER JOIN tr_event_entry_big t2 ON (t2.mbr_id = t1.mbr_id)
WHERE   t1.mbr_gd = 'GOLD'
AND     t2.entry_dtm >= TO_DATE('20230114','YYYYMMDD')
AND     t2.entry_dtm <  TO_DATE('20230115','YYYYMMDD')
GROUP BY t1.mbr_id;

-- xml_mapper_sql_id: select_mbr_big_group_01
EXPLAIN
/*+ NestLoop(t1 t2) Leading((t1 t2)) */
SELECT  t1.mbr_id ,MAX(t1.nick_nm) nick_nm ,COUNT(*) entry_cnt
FROM    ms_mbr_big t1
        INNER JOIN tr_event_entry_big t2 ON (t2.mbr_id = t1.mbr_id)
WHERE   t1.mbr_gd = 'GOLD'
AND     t2.entry_dtm >= TO_DATE('20230114','YYYYMMDD')
AND     t2.entry_dtm <  TO_DATE('20230115','YYYYMMDD')
GROUP BY t1.mbr_id;

PostgreSQL을 사용하면서, XML Mapper SQL_ID 위치를 고민하고 있다면 참고하기 바란다.