13.3. ¸í½ÃÀûÀÎJOIN±¸¹®·Î planner¸¦ Á¦¾îÇÑ´Ù

¸í½ÃÀûÀÎJOIN±¸¹®À» »ç¿ëÇØ Äõ¸® planner¸¦ ¾î´À Á¤µµ Á¦¾îÇÒ ¼ö ÀÖ½À´Ï´Ù. ¾î°¼­ ÀÌ·± °ÍÀÌ ¹®Á¦°¡ µÇ´ÂÁö, ¿ì¼± ±× ¹è°æÀ» º¼ Çʿ䰡 ÀÖ½À´Ï´Ù.

´Ü¼øÇÑ Äõ¸®ÇØ ¿¹¸¦ µé¸é

SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;

±×·³, planner´Â ÀÚÀ¯·Ó°Ô ÁÖ¾îÁø Å×À̺íÀ» ÀÓÀÇÀÇ ¼ø¼­·Î Á¶ÀÎÇÒ ¼ö ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¸é, WHEREÁ¶°ÇÀÇa.id = b.id¸¦ »ç¿ëÇØ ¿ì¼± A¿Í B¸¦ Á¶ÀÎÇØ, ´Ù¸¥WHEREÁ¶°ÇÀ» »ç¿ëÇØ ±× Á¶ÀÎ Å×ÀÌºí¿¡ C¸¦ Á¶ÀÎÇÑ´Ù°í ÇÏ´Â °èȹÀ» ¼¼¿ï ¼ö ÀÖ½À´Ï´Ù. ȤÀº B¿Í C¸¦ Á¶ÀÎÇØ, ±× °á°ú¿¡ A¸¦ Á¶ÀÎÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ȤÀº A¿Í C¸¦ Á¶ÀÎÇØ, ±× °á°ú¿¡ B¸¦ Á¶ÀÎÇÒ ¼öµµ ÀÖ°ÚÁö¿ä. ±×·¯³ª ±×·¯¸é È¿À²ÀÌ ÁÁÁö ¾Ê½À´Ï´Ù. ¿Ö³ÄÇϸé, Á¶ÀÎÀÇ ÃÖÀûÈ­¸¦ ½Ç½ÃÇϱâ À§Çؼ­ Àû¿ëÇÒ ¼ö ÀÖ´Â Á¶°ÇÀÌWHERE±¸¹®¿¡ ¾ø±â ¶§¹®¿¡, A¿Í CÀÇ ÀüÁ÷ÀûÀÌ ¸¸µé¾îÁö±â ¶§¹®ÀÔ´Ï´Ù (PostgreSQLÀÇ ¼öÇàÀÚ¿¡¼­´Â Á¶ÀÎÀº ¸ðµÎ 2°³ÀÇ Å×À̺íÀÇ »çÀÌ¿¡ ÇàÇØÁö±â ¶§¹®¿¡, ÀÌ¿Í °°ÀÌ ÇØ 1°³Çϳª °á°ú¸¦ ¸¸µé¾î °¡Áö ¾ÊÀ¸¸é ¾ÈµË´Ï´Ù). Áß¿äÇÑ °ÍÀº ÀÌ·¯ÇÑ ´Ù¸¥ Á¶ÀÎÀÇ ¹æ¹ýÀº ÀǹÌÀûÀ¸·Î´Â °°Àº °á°úÀÌÁö¸¸, ½ÇÇà ÄÚ½ºÆ®´Â Å©°Ô ´Ù¸¦ °¡´É¼ºÀÌ ÀÖ´Ù°í ÇÏ´Â °ÍÀÔ´Ï´Ù. ±×·¯´Ï±î, planner´Â °¡Àå È¿À²ÀÇ ÁÁÀº Ç÷£À» ã±â À§Çؼ­ °¡´ÉÇÑ Ç÷£À» ¸ðµÎ °Ë»çÇÕ´Ï´Ù.

Á¶ÀÎÀÇ ´ë»óÀÌ °Ü¿ì 2, 3°³ÀÇ Å×À̺íÀ̶ó¸é °ÆÁ¤ÇÏ´Â ¸¸Å­ Á¶ÀÎÀÇ Á¾·ù´Â ¸¹Áö ¾Ê½À´Ï´Ù. ±×·¯³ª Å×À̺í¼ö°¡ Áõ°¡ÇÏ¸é °¡´ÉÇÑ Á¶ÀÎÀÇ ¼ö´Â Áö¼öÇÔ¼öÀûÀ¸·Î Áõ°¡ÇØ °©´Ï´Ù. 10 Á¤µµ ÀÌ»óÀ¸·Î Å×À̺íÀÌ Áõ°¡Çϸé, ¸ðµç °¡´É¼ºÀ» ÇØµé º¸°í ºÎ¼ö¾î¿¡ Ž»öÇÏ´Â °ÍÀº ÀÌ¹Ì ½Ç¿ëÀûÀÎ °ÍÀº ¾ø¾îÁý´Ï´Ù. 6À̳ª 7°³ÀÇ Å×À̺íÁ¶Â÷µµ, °èȹÀ» ÀÛ¼ºÇÒ ½Ã°£ÀÌ ¹«½ÃÇÒ ¼ö ¾ø°Ô µË´Ï´Ù. Å×À̺íÀÇ ¼ö°¡ ³Ê¹« ¸¹À» ¶§´Â PostgreSQLÀÇ planner´Â ÇØ ÇØÀÇ Å½»öÀ¸·ÎºÎÅÍ, ÇÑÁ¤µÈ °¡´É¼º¸¸À» Ž»öÇÏ´Â À¯ÀüÀûÈ®·üÀûÀΠŽ»öÀ¸·Î ¹Ù²ò´Ï´Ù (º¯È¯ÀÇ thresholdÀºgeqo_threshold½ÇÇà½Ã ÆÄ¶ó¹ÌÅÍ·Î ¼³Á¤µË´Ï´Ù). À¯ÀüÀû Ž»öÀº ªÀº ½Ã°£¿¡ Ž»öÀ» ½Ç½ÃÇÏÁö¸¸, ¹Ýµå½Ã ÃÖÀûÀÎ °èȹÀ» ã¾Æ³½´Ù°í´Â ÇÒ ¼ö ¾ø½À´Ï´Ù.

¿ÜºÎ Á¶ÀÎÀÌ Æ÷ÇԵǴ °Í °°Àº Äõ¸®¿¡¼­´Â planner¿¡´Â º¸ÅëÀÇ(³»ºÎ) Á¶ÀÎÀ¸·ÎºÎÅÍ ¼±ÅÃÀÇ ¿©Áö°¡ ÀÛ¾ÆÁý´Ï´Ù. ¿¹¸¦ µé¸é, ´ÙÀ½°ú °°Àº Äõ¸®¸¦ »ý°¢ÇÕ´Ï´Ù.

SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);

ÀÌ Äõ¸®ÀÇ °Ë»ö Á¶°ÇÀº Àü¼úÀÇ ¿¹¿Í Ç¥¸éÀûÀ¸·Î´Â ºñ½ÁÇÑ °Íó·³ »ý°¢µÇÁö¸¸, B¿Í CÀÇ Á¶ÀÎ °á°úÀÇ Çà¿¡ ÀûÇÕÇÏÁö ¾Ê´Â AÀÇ °¢ ÇàÀÌ Ãâ·ÂµÇÁö ¾ÊÀ¸¸é ¾È µÇ±â ¶§¹®¿¡, ÀǹÌÀûÀ¸·Î´Â ´Ù¸¨´Ï´Ù. µû¶ó¼­, ¿©±â¿¡¼­´Â planner¿¡´Â Á¶ÀÎ ¼ø¼­¿¡ °üÇØ¼­ ¼±ÅÃÀÇ ¿©Áö°¡ ¾ø½À´Ï´Ù. ¿ì¼± B¿Í C¸¦ Á¶ÀÎÇØ, ±× °á°ú¿¡ A¸¦ Á¶ÀÎÇØ¾ß ÇÕ´Ï´Ù. ±×·¯ÇÑ ÀÌÀ¯·Î, ÀÌ Äõ¸®¿¡¼­´Â °èȹÀ» ¼¼¿ì´Âµ¥ ÇÊ¿ä·Î ÇÏ´Â ½Ã°£Àº ÀüÀÇ ¿¹º¸´Ù ª¾ÆÁý´Ï´Ù. ±× ¿ÜÀÇ °æ¿ì, planner°¡ ¾ÈÀüÇÑ Á¶ÀÎ ¼ø¼­¸¦ º¹¼ö °áÁ¤ÇÒ ¼ö ÀÖÀ» °¡´É¼ºÀÌ ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¾î, ÀÌÇϸ¦ »ý°¢ÇØ º¸°Ú½À´Ï´Ù.

SELECT * FROM a LEFT JOIN b ON (a.bid = b.id) LEFT JOIN c ON (a.cid = c.id);

ÀÌ °æ¿ì, A¸¦ ¸ÕÀú B¿Í Á¶ÀÎÇØµµ C¿Í Á¶ÀÎÇØµµ À¯È¿ÇÕ´Ï´Ù. Çö½ÃÁ¡¿¡¼­´Â FULL JOIN¸¸ÀÌ ¿ÏÀüÇÏ°Ô Á¶ÀÎ ¼ø¼­¸¦ Á¦ÇÑÇÕ´Ï´Ù. LEFT JOIN³ª RIGHT JOIN¸¦ Æ÷ÇÔÇÑ, ´ëºÎºÐÀÇ ½ÇÇà ȯ°æ¿¡¼­´Â ÀϺΠȮÀåÀ¸·Î ÀçÁ¶Á¤ÇÒ ¼ö ÀÖ½À´Ï´Ù.

¸í½ÃÀûÀÎ ³»ºÎ Á¶ÀÎ ±¸¹®(INNER JOIN, CROSS JOIN, Àå½ÄÀÌ ¾ø´Â JOIN)Àº ÀǹÌÀûÀ¸·Î´Â FROM³»ÀÇ ÀÔ·Â ¸±·¹À̼ÇÀÇ ¿­°Å¿Í °°½À´Ï´Ù. µû¶ó¼­, Á¶ÀÎ ¼ø¼­¸¦ Á¦¾àÇÒ ÇÊ¿ä´Â ¾ø½À´Ï´Ù.

´ëºÎºÐÀÇ Á¾·ùÀÇJOIN´Â ¿ÏÀüÇÏ°Ô Á¶ÀÎ ¼ø¼­¸¦ Á¦¾àÇÏÁö¸¸, PostgreSQLÄõ¸® planner¿¡, ¸ðµçJOIN±¸¹®¿¡ ´ëÇØ¼­ ¿ì¼± Á¶ÀÎ ¼ø¼­¸¦ Á¦ÇѽÃų ¼ö ÀÖ½À´Ï´Ù. ¿¹¸¦ µé¸é, ÀÌÇÏÀÇ 3°³ÀÇ Äõ¸®´Â ³í¸®ÀûÀ¸·Î µ¿ÀÏÇÕ´Ï´Ù.

SELECT * FROM a, b, c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a CROSS JOIN b CROSS JOIN c WHERE a.id = b.id AND b.ref = c.id;
SELECT * FROM a JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);

±×·¯³ª planner¿¡JOINÀÇ Â÷·Ê¸¦ Áö۵µ·Ï ÀüÇßÀ» °æ¿ì, 2¹øÂ°¿Í 3¹øÂ°ÀÇ Äõ¸®´Â ÃÖÃÊÀÇ °Íº¸´Ù ªÀº ½Ã°£¿¡ °èȹÀ» ¼¼¿ï ¼ö ÀÖ½À´Ï´Ù. ÀÌ È¿°ú´Â 3°³ÀÇ Å×ÀÌºí¸¸ ÀÖÀ» ¶§´Â ½Å°æ¾µ Á¤µµÀÇ °ÍÀÌ ¾Æ´ÏÁö¸¸, ¸¹Àº Å×À̺íÀ» Á¶ÀÎÇÒ ¶§´Â ±¸¿øÀÚ ¿ªÇÒÀ» ÇØ ÁÙ °ÍÀÔ´Ï´Ù.

planner¸¦ °­Á¦ÀûÀ¸·Î ¸í½ÃÀûÀÎJOIN¿¡ ÀáÀçÇÏ´Â Á¶ÀÎ ¼ø¼­¿¡ µû¸£°Ô ÇÏ·Á¸é, join_collapse_limit½ÇÇà½Ã ÆÄ¶ó¹ÌÅ͸¦ 1À¸·Î ¼³Á¤ÇØ Áֽʽÿä (ÀÌÇÏ·Î ´Ù¸¥ ÃëÇÒ ¼ö ÀÖ´Â °ª¿¡ ´ëÇØ ¼³¸íÇÕ´Ï´Ù).

°Ë»ö ½Ã°£À» Àý¾àÇϱâ À§Çؼ­, Á¶ÀÎ ¼ø¼­¸¦ ¿ÏÀüÇÏ°Ô ¼Ó¹Ú ÇÒ ÇÊ¿ä´Â ¾ø½À´Ï´Ù. ¿Ö³ÄÇϸé, ´Ü¼øÇÑFROM¸®½ºÆ®ÀÇ Ç׸ñ³»¿¡JOIN¿¬»êÀÚ¸¦ »ç¿ëÇØµµ »ó°ü¾ø±â ¶§¹®ÀÔ´Ï´Ù. ¿¹¸¦ µé¸é, ´ÙÀ½ÀÇ ¿¹ÀÔ´Ï´Ù.

SELECT * FROM a CROSS JOIN b, c, d, e WHERE ...;

With join_collapse_limit = 1, this forces the planner to join A to B before joining them to other tables, but doesn't constrain its choices otherwise. In this example, the number of possible join orders is reduced by a factor of 5. --> join_collapse_limit = 1À¸·Î ÇßÀ» °æ¿ì, planner´Â °­Á¦ÀûÀ¸·Î ´Ù¸¥ Å×À̺í°ú Á¶ÀÎÇϱâ Àü¿¡ A¿Í B¸¦ Á¶ÀÎÇÏÁö¸¸, ±× À̿ܿ¡ ´ëÇØ¼­´Â ƯÈ÷ ±¸¼ÓÀº ¾ø½À´Ï´Ù. ÀÌ ¿¹¿¡¼­´Â Á¶ÀÎ ¼ø¼­ÀÇ È帴 5ºÐÀÇ 1À¸·Î °¨¼ÒÇÕ´Ï´Ù.

ÀÌ·¯ÇÑ ¹æ¹ýÀ¸·Î plannerÀÇ °Ë»ö¿¡ Á¦¾àÀ» ´õÇÏ´Â °ÍÀº °èȹ ÀÛ¼º ½Ã°£ÀÇ ´ÜÃà°ú planner¿¡ ´ëÇÑ ¶Ù¾î³­ Äõ¸® °èȹÀ» ¹æÇâÁöÀ» ¼ö ÀÖ½À´Ï´Ù. ÀÌ µÑÀº ¸ðµÎ À¯¿ëÇÑ ±â¹ýÀÔ´Ï´Ù. planner°¡ µÚ¶³¾îÁø Á¶ÀÎ ¼ø¼­¸¦ µðÆúÆ®·Î ¼±ÅÃÇÑ´Ù¸é, JOIN±¸¹® °æÀ¯·Î º¸´Ù ÁÁÀº Â÷·Ê¸¦ ¼±ÅÃÇϵµ·Ï °­Á¦ÇÒ ¼ö ÀÖ½À´Ï´Ù. ´Ù¸¸, º¸´Ù ÁÁÀº Â÷·Ê¸¦ ÀÌÇØÇÑ´Ù°í °¡Á¤ÇؾßÇÕ´Ï´Ù. À̰ÍÀº ½ÇÇèÇØ º¼ °ÍÀ» ±ÇÇÕ´Ï´Ù.

Äõ¸® ÀÛ¼º ½Ã°£¿¡ ¿µÇâÀ» ÁÖ´Â ¹ÐÁ¢ÇÏ°Ô °ü·ÃµÈ ¹®Á¦´Â ÇÏÀ§ Äõ¸®¿¡¼­ ºÎ¸ð Äõ¸®·Î Ãæµ¹µÇ´Â °ÍÀÔ´Ï´Ù. ¿¹¸¦ µé¸é, ÀÌÇϸ¦ »ý°¢ÇØ º¸°Ú½À´Ï´Ù.

SELECT *
FROM x, y,
    (SELECT * FROM a, b, c WHERE something) AS ss
WHERE somethingelse;

ÀÌ·± »óȲÀº Á¶ÀÎÀ» Æ÷ÇÔÇÏ´Â ºä¸¦ »ç¿ëÇÔÀ¸·Î½á ¹ß»ýµË´Ï´Ù. ºäÀÇ SELECT ·êÀº ºä ÂüÁ¶ °ø°£¿¡ Ãß°¡µÉ °ÍÀÔ´Ï´Ù. ¿µÇ⠹ޱ⠽¬¿î Äõ¸®´Â À§¿Í °°½À´Ï´Ù. ÀϹÝÀûÀ¸·Î planner´Â ºÎ¸ð Äõ¸®¿¡¼­ ÇÏÀ§ Äõ¸®°¡ Ãæµ¹Çϵµ·Ï ½ÃµµÇÒ °ÍÀÔ´Ï´Ù.

SELECT * FROM x, y, a, b, c WHERE something AND somethingelse;

À̰ÍÀº º¸Åë, ÇÏÀ§ Äõ¸®ÀÇ °èȹÀ» º°µµ ÀÛ¼ºÇÏ´Â °Íº¸´Ù ¶Ù¾î³­ °èȹÀ» ÀÛ¼ºÇÕ´Ï´Ù (¿¹¸¦ µé¸é, ¿ÜºÎÀÇWHEREÁ¶°ÇÀº X¸¦ A¿¡ Á¶ÀÎÇÏ°Ô µÇ¾î, ¿ì¼± A°¡ ¸¹Àº ÇàÀÌ Á¦°ÅµË´Ï´Ù. À̰Ϳ¡ ÀÇÇØ, ÇÏÀ§ Äõ¸®ÀÇ ¿ÏÀüÇÑ ³í¸®Àû Ãâ·ÂÀÌ ºÒÇÊ¿äÇÏ°Ô µË´Ï´Ù). ±×·¯³ª µ¿½Ã¿¡ °èȹ ÀÛ¼º ½Ã°£ÀÌ Áõ°¡ÇÕ´Ï´Ù. ÀÌ °æ¿ì, 2°³ÀÇ 3¹æ¹ýÀÇ Á¶ÀÎ ¹®Á¦·ÎºÎÅÍ 5¹æ¹ýÀÇ Á¶ÀÎ ¹®Á¦°¡ µË´Ï´Ù. Èĺ¸ ¼ö´Â Áö¼öÇÔ¼öÀûÀ¸·Î Áõ°¡Çϱâ À§ÇØ, À̰ÍÀº Å« Â÷À̰¡ µË´Ï´Ù. planner´Â ´ë±Ô¸ð Á¶ÀÎ °Ë»ö ¹®Á¦·Î ¼ûÀÌ ¸·È÷Áö ¾Ê°Ô, ¸¸¾àfrom_collapse_limit°³ÀÇFROMÇ׸ñÀÌ ºÎ¸ð Äõ¸®·Î ¹ß»ýÇØ ¹ö¸®´Â °æ¿ì´Â ÇÏÀ§ Äõ¸®¸¦ Ãæµ¹ÇÏÁö ¾Êµµ·Ï ÇØ¼­ ¾ïÁ¦ÇÕ´Ï´Ù. ÀÌ ½ÇÇà½Ã ÆÄ¶ó¹ÌÅÍÀÇ °ªÀ» »óÇÏ·Î Á¶Á¤ÇÏ¿© °èȹ ÀÛ¼º ½Ã°£°ú °èȹÀÇ ÁúÀ» trade off ÇÒ ¼ö ÀÖ½À´Ï´Ù.

¾çÀÚ´Â °ÅÀÇ °°Àº °ÍÀ» ½Ç½ÃÇϱ⠶§¹®¿¡, from_collapse_limit¶ó°íjoin_collapse_limit´Â ºñ½ÁÇÑ À̸§À» °¡Áý´Ï´Ù. ´Ù¸¥ ÇÑÂÊÀº ºÎ¼±ÅõµÀÇ"flatten out"¸¦ planner°¡ ¾ðÁ¦ ½Ç½ÃÇÏ´ÂÁö¸¦ Á¦¾îÇϰí, ´Ù¸¥ ÇÑÂÊÀº ¸í½ÃÀûÀÎ Á¶ÀÎÀÇ flatten out¸¦ ¾ðÁ¦ ½Ç½ÃÇÏ´ÂÁö¸¦ Á¦¾îÇÕ´Ï´Ù. º¸Åë, join_collapse_limit¸¦from_collapse_limit¿Í °°Àº °ªÀ¸·Î ¼³Á¤(¸í½ÃÀûÀÎ ³»ºÎ Á¶Àΰú ºÎÄõ¸®ÀÇ µ¿ÀÛÀ» °°°Ô ÇÑ´Ù)ÇÏ´øÁö join_collapse_limit¸¦ 1À¸·Î ¼³Á¤(¸í½ÃÀûÀÎ Á¶ÀÎÀ¸·Î Á¶ÀÎ ¼ø¼­¸¦ Á¦¾îÇÏ°í ½ÍÀº °æ¿ì)ÇÏ´Â µÎ ¹æ¹ýÀ» ½Ç½ÃÇÕ´Ï´Ù. ±×·¯³ª °èȹ ÀÛ¼º ½Ã°£°ú ½ÇÇà ½Ã°£ »çÀÌÀÇ trade off¸¦ ÃæºÐÈ÷ ½Ç½ÃÇÏ´Â °æ¿ì´Â À̰͵éÀ» ´Ù¸¥ °ªÀ¸·Î ¼³Á¤Çصµ »ó°üÇÏÁö ¾Ê½À´Ï´Ù.