<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ko">
	<id>https://dbstudy.co.kr/w/index.php?action=history&amp;feed=atom&amp;title=%EC%A1%B0%EC%9D%B8_%ED%8A%9C%EB%8B%9D_%EC%8B%AC%ED%99%94</id>
	<title>조인 튜닝 심화 - 편집 역사</title>
	<link rel="self" type="application/atom+xml" href="https://dbstudy.co.kr/w/index.php?action=history&amp;feed=atom&amp;title=%EC%A1%B0%EC%9D%B8_%ED%8A%9C%EB%8B%9D_%EC%8B%AC%ED%99%94"/>
	<link rel="alternate" type="text/html" href="https://dbstudy.co.kr/w/index.php?title=%EC%A1%B0%EC%9D%B8_%ED%8A%9C%EB%8B%9D_%EC%8B%AC%ED%99%94&amp;action=history"/>
	<updated>2026-11-04T06:04:14Z</updated>
	<subtitle>이 문서의 편집 역사</subtitle>
	<generator>MediaWiki 1.39.10</generator>
	<entry>
		<id>https://dbstudy.co.kr/w/index.php?title=%EC%A1%B0%EC%9D%B8_%ED%8A%9C%EB%8B%9D_%EC%8B%AC%ED%99%94&amp;diff=1994&amp;oldid=prev</id>
		<title>Dbstudy: 상단 배너를 {{타이틀 주제}} 틀로 교체</title>
		<link rel="alternate" type="text/html" href="https://dbstudy.co.kr/w/index.php?title=%EC%A1%B0%EC%9D%B8_%ED%8A%9C%EB%8B%9D_%EC%8B%AC%ED%99%94&amp;diff=1994&amp;oldid=prev"/>
		<updated>2026-11-04T04:26:21Z</updated>

		<summary type="html">&lt;p&gt;상단 배너를 {{타이틀 주제}} 틀로 교체&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ko&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← 이전 판&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026년 11월 4일 (수) 13:26 판&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l1&quot;&gt;1번째 줄:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;1번째 줄:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;div style=&amp;quot;background:linear-gradient(135deg,#0b4d40 0%,#118a72 55%,#16a085 100%);color:#ffffff;padding:30px 36px;border-radius:14px;margin-bottom:24px;box-shadow:0 4px 14px rgba(11,77,64,0.25);&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{{타이틀 주제&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;div style&lt;/del&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;font-size:12px;letter-spacing:3px;opacity:0.8;margin-bottom:6px;&amp;quot;&amp;gt;&lt;/del&gt;ORACLE SQL TUNING · DEEP DIVE 2&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|부제 &lt;/ins&gt;= ORACLE SQL TUNING · DEEP DIVE 2&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;div style&lt;/del&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;font-size:28px;font-weight:700;line-height:1.3;&amp;quot;&amp;gt;&lt;/del&gt;조인 튜닝 심화&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|제목 &lt;/ins&gt;= 조인 튜닝 심화&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;div style&lt;/del&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;font-size:15px;opacity:0.92;margin-top:10px;line-height:1.7;&amp;quot;&amp;gt;&lt;/del&gt;NL · Hash · Sort Merge의 내부 동작, 조인 순서 결정, 서브쿼리와 쿼리 변환, 아우터 조인까지&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|설명 &lt;/ins&gt;= NL · Hash · Sort Merge의 내부 동작, 조인 순서 결정, 서브쿼리와 쿼리 변환, 아우터 조인까지&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;div style&lt;/del&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;margin-top:16px;display:flex;flex-wrap:wrap;gap:8px;&amp;quot;&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|색상 &lt;/ins&gt;= &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;초록&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;span style&lt;/del&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;background:rgba(255,255,255,0.18);border:1px solid rgba(255,255,255,0.35);padding:4px 12px;border-radius:20px;font-size:12px;&amp;quot;&amp;gt;&lt;/del&gt;선수 학습 · [[SQL 튜닝 입문]] 7장, [[인덱스 튜닝 심화]]&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/span&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|배지1 &lt;/ins&gt;= 선수 학습 · [[SQL 튜닝 입문]] 7장, [[인덱스 튜닝 심화]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;span style&lt;/del&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;background:rgba(255,255,255,0.18);border:1px solid rgba(255,255,255,0.35);padding:4px 12px;border-radius:20px;font-size:12px;&amp;quot;&amp;gt;&lt;/del&gt;커리큘럼 · 8~9주차&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/span&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|배지2 &lt;/ins&gt;= 커리큘럼 · 8~9주차&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;span style&lt;/del&gt;=&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;quot;background:rgba(255,255,255,0.18);border:1px solid rgba(255,255,255,0.35);padding:4px 12px;border-radius:20px;font-size:12px;&amp;quot;&amp;gt;&lt;/del&gt;난이도 · 중급&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/span&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|배지3 &lt;/ins&gt;= 난이도 · 중급&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;}}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&amp;lt;/div&amp;gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;__TOC__&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;__TOC__&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Dbstudy</name></author>
	</entry>
	<entry>
		<id>https://dbstudy.co.kr/w/index.php?title=%EC%A1%B0%EC%9D%B8_%ED%8A%9C%EB%8B%9D_%EC%8B%AC%ED%99%94&amp;diff=1984&amp;oldid=prev</id>
		<title>Dbstudy: 새 문서: &lt;div style=&quot;background:linear-gradient(135deg,#0b4d40 0%,#118a72 55%,#16a085 100%);color:#ffffff;padding:30px 36px;border-radius:14px;margin-bottom:24px;box-shadow:0 4px 14px rgba(11,77,64,0.25);&quot;&gt; &lt;div style=&quot;font-size:12px;letter-spacing:3px;opacity:0.8;margin-bottom:6px;&quot;&gt;ORACLE SQL TUNING · DEEP DIVE 2&lt;/div&gt; &lt;div style=&quot;font-size:28px;font-weight:700;line-height:1.3;&quot;&gt;조인 튜닝 심화&lt;/div&gt; &lt;div style=&quot;font-size:15px;opacity:0.92;margin-top:10px;line-height:1.7;&quot;&gt;NL ·...</title>
		<link rel="alternate" type="text/html" href="https://dbstudy.co.kr/w/index.php?title=%EC%A1%B0%EC%9D%B8_%ED%8A%9C%EB%8B%9D_%EC%8B%AC%ED%99%94&amp;diff=1984&amp;oldid=prev"/>
		<updated>2026-11-04T03:56:33Z</updated>

		<summary type="html">&lt;p&gt;새 문서: &amp;lt;div style=&amp;quot;background:linear-gradient(135deg,#0b4d40 0%,#118a72 55%,#16a085 100%);color:#ffffff;padding:30px 36px;border-radius:14px;margin-bottom:24px;box-shadow:0 4px 14px rgba(11,77,64,0.25);&amp;quot;&amp;gt; &amp;lt;div style=&amp;quot;font-size:12px;letter-spacing:3px;opacity:0.8;margin-bottom:6px;&amp;quot;&amp;gt;ORACLE SQL TUNING · DEEP DIVE 2&amp;lt;/div&amp;gt; &amp;lt;div style=&amp;quot;font-size:28px;font-weight:700;line-height:1.3;&amp;quot;&amp;gt;조인 튜닝 심화&amp;lt;/div&amp;gt; &amp;lt;div style=&amp;quot;font-size:15px;opacity:0.92;margin-top:10px;line-height:1.7;&amp;quot;&amp;gt;NL ·...&lt;/p&gt;
&lt;p&gt;&lt;b&gt;새 문서&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;div style=&amp;quot;background:linear-gradient(135deg,#0b4d40 0%,#118a72 55%,#16a085 100%);color:#ffffff;padding:30px 36px;border-radius:14px;margin-bottom:24px;box-shadow:0 4px 14px rgba(11,77,64,0.25);&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size:12px;letter-spacing:3px;opacity:0.8;margin-bottom:6px;&amp;quot;&amp;gt;ORACLE SQL TUNING · DEEP DIVE 2&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size:28px;font-weight:700;line-height:1.3;&amp;quot;&amp;gt;조인 튜닝 심화&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size:15px;opacity:0.92;margin-top:10px;line-height:1.7;&amp;quot;&amp;gt;NL · Hash · Sort Merge의 내부 동작, 조인 순서 결정, 서브쿼리와 쿼리 변환, 아우터 조인까지&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top:16px;display:flex;flex-wrap:wrap;gap:8px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:rgba(255,255,255,0.18);border:1px solid rgba(255,255,255,0.35);padding:4px 12px;border-radius:20px;font-size:12px;&amp;quot;&amp;gt;선수 학습 · [[SQL 튜닝 입문]] 7장, [[인덱스 튜닝 심화]]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:rgba(255,255,255,0.18);border:1px solid rgba(255,255,255,0.35);padding:4px 12px;border-radius:20px;font-size:12px;&amp;quot;&amp;gt;커리큘럼 · 8~9주차&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;background:rgba(255,255,255,0.18);border:1px solid rgba(255,255,255,0.35);padding:4px 12px;border-radius:20px;font-size:12px;&amp;quot;&amp;gt;난이도 · 중급&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== 1. 조인 방식 선택의 기준 ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:flex;flex-wrap:wrap;gap:12px;margin:14px 0;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:1 1 240px;border:1px solid #cfe9e2;border-top:4px solid #16a085;border-radius:10px;padding:14px 18px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Nested Loops&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:13px;color:#4a5a6a;&amp;quot;&amp;gt;&amp;quot;적은 건수를 &amp;#039;&amp;#039;&amp;#039;인덱스&amp;#039;&amp;#039;&amp;#039;로 빨리&amp;quot;&amp;lt;br/&amp;gt;OLTP · 부분 범위 처리 · 첫 응답 속도&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:1 1 240px;border:1px solid #cfe9e2;border-top:4px solid #2b7bb9;border-radius:10px;padding:14px 18px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Hash Join&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:13px;color:#4a5a6a;&amp;quot;&amp;gt;&amp;quot;많은 건수를 &amp;#039;&amp;#039;&amp;#039;메모리&amp;#039;&amp;#039;&amp;#039;에서 한 번에&amp;quot;&amp;lt;br/&amp;gt;배치 · 대량 집계 · 조인 인덱스 없음&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;flex:1 1 240px;border:1px solid #cfe9e2;border-top:4px solid #8e44ad;border-radius:10px;padding:14px 18px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Sort Merge Join&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;span style=&amp;quot;font-size:13px;color:#4a5a6a;&amp;quot;&amp;gt;&amp;quot;양쪽을 &amp;#039;&amp;#039;&amp;#039;정렬&amp;#039;&amp;#039;&amp;#039;해서 병합&amp;quot;&amp;lt;br/&amp;gt;비동등 조인 · 이미 정렬된 입력&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:5px solid #16a085;background:#effaf6;padding:14px 20px;margin:16px 0;border-radius:0 8px 8px 0;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;판단 질문 3가지&amp;#039;&amp;#039;&amp;#039;&amp;lt;br/&amp;gt;&lt;br /&gt;
① 조인 결과(또는 Outer 집합)가 &amp;#039;&amp;#039;&amp;#039;몇 건&amp;#039;&amp;#039;&amp;#039;인가? — 소량이면 NL, 대량이면 Hash&amp;lt;br/&amp;gt;&lt;br /&gt;
② Inner 쪽 &amp;#039;&amp;#039;&amp;#039;조인 컬럼에 인덱스&amp;#039;&amp;#039;&amp;#039;가 있는가? — 없으면 NL은 사실상 불가&amp;lt;br/&amp;gt;&lt;br /&gt;
③ 사용자에게 &amp;#039;&amp;#039;&amp;#039;첫 화면만&amp;#039;&amp;#039;&amp;#039; 빨리 보여주면 되는가, &amp;#039;&amp;#039;&amp;#039;전체 결과&amp;#039;&amp;#039;&amp;#039;가 필요한가?&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 2. Nested Loops Join 심화 ==&lt;br /&gt;
=== 2.1 동작 원리 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
  for each row in OUTER (Driving)          ← 1회 스캔&lt;br /&gt;
      search INNER using index on join key ← Outer 행 수만큼 반복 (Starts)&lt;br /&gt;
      if match → return row&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 총 비용 ≈ Outer 스캔 비용 + &amp;#039;&amp;#039;&amp;#039;Outer 행 수 × (Inner 인덱스 탐색 + 테이블 액세스)&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* 결과를 &amp;#039;&amp;#039;&amp;#039;한 건씩 바로 반환&amp;#039;&amp;#039;&amp;#039;할 수 있어 부분 범위 처리에 유리하다.&lt;br /&gt;
&lt;br /&gt;
=== 2.2 NL 조인 튜닝 포인트 ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#0b4d40;color:#fff;&amp;quot;&lt;br /&gt;
! 포인트 !! 내용&lt;br /&gt;
|-&lt;br /&gt;
| Driving 집합 최소화 || Outer 쪽 조건을 최대한 적용해 반복 횟수(Starts) 감소&lt;br /&gt;
|-&lt;br /&gt;
| Inner 인덱스 || 조인 컬럼 + Inner 쪽 필터 조건을 함께 포함한 결합 인덱스&lt;br /&gt;
|-&lt;br /&gt;
| Inner 테이블 액세스 || 인덱스에서 걸러 테이블 방문 최소화, 필요 시 커버링&lt;br /&gt;
|-&lt;br /&gt;
| 조인 순서 || 걸러지는 비율이 큰 테이블을 먼저 조인 (3개 이상 조인 시)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 2.3 NL 조인 실행계획 형태 (11g+) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
|  1 |  NESTED LOOPS                 |             |     ← 테이블 액세스용 NL&lt;br /&gt;
|  2 |   NESTED LOOPS                |             |     ← 인덱스 탐색용 NL&lt;br /&gt;
|  3 |    TABLE ACCESS BY INDEX ROWID| TB_CUSTOMER |     ← Outer&lt;br /&gt;
|* 4 |     INDEX RANGE SCAN          | IX_CUST_01  |&lt;br /&gt;
|* 5 |    INDEX RANGE SCAN           | IX_ORDER_01 |     ← Inner 인덱스&lt;br /&gt;
|  6 |   TABLE ACCESS BY INDEX ROWID | TB_ORDER    |     ← Inner 테이블 (일괄 처리)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* NL이 두 번 나오는 것은 &amp;#039;&amp;#039;&amp;#039;NLJ Batching&amp;#039;&amp;#039;&amp;#039;(Inner 인덱스 결과를 모아 테이블 I/O를 일괄 처리) 때문이다. 정상이다.&lt;br /&gt;
* 이 방식에서도 결과 순서가 Outer 순서와 다를 수 있으므로 정렬은 반드시 &amp;lt;code&amp;gt;ORDER BY&amp;lt;/code&amp;gt;로 명시한다.&lt;br /&gt;
&lt;br /&gt;
== 3. Hash Join 심화 ==&lt;br /&gt;
=== 3.1 동작 원리 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
  [Build 단계]  작은 집합(Build Input)을 읽어 조인 키로 해시 테이블 생성 → PGA&lt;br /&gt;
  [Probe 단계]  큰 집합(Probe Input)을 읽으며 해시 테이블 탐색 → 일치하면 반환&lt;br /&gt;
&lt;br /&gt;
  HASH JOIN&lt;br /&gt;
    ├─ TABLE ACCESS FULL  TB_CUSTOMER   ← 위쪽 = Build (작아야 함)&lt;br /&gt;
    └─ TABLE ACCESS FULL  TB_ORDER      ← 아래쪽 = Probe&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3.2 메모리와 성능 ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#e8f6f2;&amp;quot;&lt;br /&gt;
! 처리 방식 !! 조건 !! 실행계획 표시&lt;br /&gt;
|-&lt;br /&gt;
| Optimal || Build 해시 테이블이 PGA에 모두 들어감 || Used-Mem (0)&lt;br /&gt;
|-&lt;br /&gt;
| One-Pass || 일부를 Temp에 쓰고 한 번 더 읽음 || Used-Mem (1), Used-Tmp&lt;br /&gt;
|-&lt;br /&gt;
| Multi-Pass || 여러 번 Temp를 오감 (매우 느림) || Used-Mem (n)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- 현재/최근 작업 영역 사용 현황&lt;br /&gt;
SELECT sql_id, operation_type, policy,&lt;br /&gt;
       ROUND(estimated_optimal_size/1024/1024) AS opt_mb,&lt;br /&gt;
       ROUND(last_memory_used/1024/1024)       AS used_mb,&lt;br /&gt;
       last_execution, optimal_executions, onepass_executions, multipasses_executions&lt;br /&gt;
  FROM v$sql_workarea&lt;br /&gt;
 WHERE sql_id = &amp;#039;&amp;amp;sql_id&amp;#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 3.3 Hash Join 튜닝 포인트 ===&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Build 집합을 작게&amp;#039;&amp;#039;&amp;#039; — 조건을 먼저 적용, 필요한 컬럼만 SELECT (해시 테이블 크기 = 행 수 × 컬럼 크기)&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Build/Probe 지정&amp;#039;&amp;#039;&amp;#039; — &amp;lt;code&amp;gt;LEADING(작은쪽) USE_HASH(큰쪽)&amp;lt;/code&amp;gt;, 또는 &amp;lt;code&amp;gt;SWAP_JOIN_INPUTS(t)&amp;lt;/code&amp;gt;로 Build 지정&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;양쪽 읽기 비용&amp;#039;&amp;#039;&amp;#039; — Hash Join은 각 집합을 1번만 읽으므로, 각 집합 &amp;#039;&amp;#039;&amp;#039;자체의 액세스 효율&amp;#039;&amp;#039;&amp;#039;(Full Scan, 파티션 프루닝, 병렬)이 전체 성능을 좌우&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;= 조인 조건만 가능&amp;#039;&amp;#039;&amp;#039; — 비동등 조인은 Hash Join 불가&lt;br /&gt;
&lt;br /&gt;
=== 3.4 NL vs Hash 실측 비교 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- 대상: VIP 고객(5,000명)의 최근 1년 주문 집계&lt;br /&gt;
SELECT /*+ GATHER_PLAN_STATISTICS LEADING(c) USE_NL(o) */&lt;br /&gt;
       c.cust_no, SUM(o.order_amt)&lt;br /&gt;
  FROM lab_cust c JOIN lab_order o ON o.cust_no = c.cust_no&lt;br /&gt;
 WHERE c.grade_cd = &amp;#039;VIP&amp;#039; AND o.order_dt &amp;gt;= ADD_MONTHS(SYSDATE, -12)&lt;br /&gt;
 GROUP BY c.cust_no;&lt;br /&gt;
&lt;br /&gt;
SELECT /*+ GATHER_PLAN_STATISTICS LEADING(c) USE_HASH(o) */&lt;br /&gt;
       c.cust_no, SUM(o.order_amt)&lt;br /&gt;
  FROM lab_cust c JOIN lab_order o ON o.cust_no = c.cust_no&lt;br /&gt;
 WHERE c.grade_cd = &amp;#039;VIP&amp;#039; AND o.order_dt &amp;gt;= ADD_MONTHS(SYSDATE, -12)&lt;br /&gt;
 GROUP BY c.cust_no;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;text-align:center;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#0b4d40;color:#fff;&amp;quot;&lt;br /&gt;
! 방식 !! Inner Starts !! 테이블 랜덤 액세스 !! Buffers (예) !! 판단&lt;br /&gt;
|-&lt;br /&gt;
| NL || 5,000 || 수십만 회 || 약 400K || 결과가 대량이라 비효율&lt;br /&gt;
|-&lt;br /&gt;
| Hash || 1 || 0 (Full Scan) || 약 16K || &amp;#039;&amp;#039;&amp;#039;이 경우 유리&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;div style=&amp;quot;font-size:13px;color:#4a5a6a;&amp;quot;&amp;gt;※ 수치는 [[실행계획 읽기 실습]]의 LAB 테이블 기준 예시. 직접 실행해 비교해 보자.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 4. Sort Merge Join ==&lt;br /&gt;
* 양쪽 입력을 조인 키로 &amp;#039;&amp;#039;&amp;#039;정렬&amp;#039;&amp;#039;&amp;#039;한 후 병합한다. 정렬은 PGA에서 수행된다.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;적합한 경우&amp;#039;&amp;#039;&amp;#039; — 비동등 조인(&amp;lt;code&amp;gt;BETWEEN&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;lt;&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;amp;gt;&amp;lt;/code&amp;gt;), 양쪽 모두 이미 인덱스 등으로 정렬되어 있음, Hash Join이 불가능한 조건&lt;br /&gt;
* &amp;lt;code&amp;gt;MERGE JOIN CARTESIAN&amp;lt;/code&amp;gt;이 실행계획에 보이면 &amp;#039;&amp;#039;&amp;#039;조인 조건 누락&amp;#039;&amp;#039;&amp;#039;이나 카디널리티 1로 잘못 추정된 경우를 의심한다.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- 비동등 조인 예: 주문 금액 구간별 등급 매핑&lt;br /&gt;
SELECT /*+ USE_MERGE(g) */ o.order_no, g.amt_grade&lt;br /&gt;
  FROM tb_order o&lt;br /&gt;
  JOIN tb_amt_grade g ON o.order_amt BETWEEN g.min_amt AND g.max_amt&lt;br /&gt;
 WHERE o.order_dt &amp;gt;= TRUNC(SYSDATE);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 5. 조인 순서 ==&lt;br /&gt;
=== 5.1 조인 순서 결정 원칙 ===&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Driving 테이블&amp;#039;&amp;#039;&amp;#039; — 자체 조건으로 가장 많이 걸러지는(결과 건수가 가장 적은) 테이블&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;다음 조인 대상&amp;#039;&amp;#039;&amp;#039; — 조인 후 &amp;#039;&amp;#039;&amp;#039;건수가 가장 많이 줄어드는&amp;#039;&amp;#039;&amp;#039; 테이블을 먼저&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;건수를 늘리는 조인&amp;#039;&amp;#039;&amp;#039;(1:N의 N쪽)은 가능한 한 뒤로&lt;br /&gt;
# 3개 이상 조인은 &amp;lt;code&amp;gt;LEADING(t1 t2 t3)&amp;lt;/code&amp;gt;로 &amp;#039;&amp;#039;&amp;#039;전체 순서&amp;#039;&amp;#039;&amp;#039;를 명시 (&amp;lt;code&amp;gt;ORDERED&amp;lt;/code&amp;gt;보다 명확)&lt;br /&gt;
&lt;br /&gt;
=== 5.2 조인 순서 예 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- 조건: 특정 상품분류(1%), 최근 7일 주문(0.7%), 서울 고객(20%)&lt;br /&gt;
SELECT /*+ LEADING(p oi o c) USE_NL(oi) USE_NL(o) USE_HASH(c) */&lt;br /&gt;
       c.cust_nm, o.order_no, p.prod_nm, oi.order_qty&lt;br /&gt;
  FROM tb_product    p&lt;br /&gt;
  JOIN tb_order_item oi ON oi.prod_cd  = p.prod_cd&lt;br /&gt;
  JOIN tb_order      o  ON o.order_no  = oi.order_no&lt;br /&gt;
  JOIN tb_customer   c  ON c.cust_no   = o.cust_no&lt;br /&gt;
 WHERE p.cate_cd   = :cate&lt;br /&gt;
   AND o.order_dt &amp;gt;= TRUNC(SYSDATE) - 7&lt;br /&gt;
   AND c.region    = &amp;#039;서울&amp;#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 위 순서가 정답은 아니다. &amp;#039;&amp;#039;&amp;#039;주문(최근 7일) → 주문상세 → 상품&amp;#039;&amp;#039;&amp;#039; 순서가 나을 수도 있다. 각 순서를 실측해 &amp;#039;&amp;#039;&amp;#039;단계별 A-Rows가 가장 빨리 줄어드는&amp;#039;&amp;#039;&amp;#039; 순서를 고른다.&lt;br /&gt;
&lt;br /&gt;
== 6. 서브쿼리와 쿼리 변환 ==&lt;br /&gt;
=== 6.1 서브쿼리 처리 방식 ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#0b4d40;color:#fff;&amp;quot;&lt;br /&gt;
! 방식 !! 동작 !! 실행계획 !! 힌트&lt;br /&gt;
|-&lt;br /&gt;
| Unnesting (조인 변환) || 서브쿼리를 조인으로 풀어 조인 방식·순서 선택 가능 || NESTED LOOPS SEMI, HASH JOIN SEMI/ANTI || &amp;lt;code&amp;gt;UNNEST&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;NL_SJ&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;HASH_SJ&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Filter || 메인 행마다 서브쿼리 실행, &amp;#039;&amp;#039;&amp;#039;입력값별 결과 캐싱&amp;#039;&amp;#039;&amp;#039; || FILTER (자식 2개) || &amp;lt;code&amp;gt;NO_UNNEST&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pushing Subquery || 서브쿼리 필터를 실행계획 앞단계에서 먼저 수행 || FILTER 위치 변화 || &amp;lt;code&amp;gt;PUSH_SUBQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Semi Join / Anti Join ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- EXISTS → Semi Join: 일치하는 첫 행을 찾으면 Inner 탐색 중단&lt;br /&gt;
SELECT c.* FROM tb_customer c&lt;br /&gt;
 WHERE EXISTS (SELECT 1 FROM tb_order o WHERE o.cust_no = c.cust_no AND o.order_dt &amp;gt;= :d);&lt;br /&gt;
&lt;br /&gt;
-- NOT EXISTS → Anti Join&lt;br /&gt;
SELECT c.* FROM tb_customer c&lt;br /&gt;
 WHERE NOT EXISTS (SELECT 1 FROM tb_order o WHERE o.cust_no = c.cust_no);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;border-left:5px solid #c0392b;background:#fdf1ef;padding:12px 18px;margin:14px 0;border-radius:0 8px 8px 0;&amp;quot;&amp;gt;&lt;br /&gt;
⚠ &amp;#039;&amp;#039;&amp;#039;NOT IN과 NULL&amp;#039;&amp;#039;&amp;#039; — &amp;lt;code&amp;gt;WHERE cust_no NOT IN (SELECT cust_no FROM tb_order)&amp;lt;/code&amp;gt;에서 서브쿼리 결과에 &amp;#039;&amp;#039;&amp;#039;NULL이 하나라도&amp;#039;&amp;#039;&amp;#039; 있으면 결과는 &amp;#039;&amp;#039;&amp;#039;0건&amp;#039;&amp;#039;&amp;#039;이다. 의도가 &amp;quot;주문 없는 고객&amp;quot;이라면 &amp;lt;code&amp;gt;NOT EXISTS&amp;lt;/code&amp;gt;를 쓴다. (Oracle은 NULL-Aware Anti Join &amp;lt;code&amp;gt;HASH JOIN ANTI NA&amp;lt;/code&amp;gt;로 처리하지만 의미는 그대로다.)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 6.3 스칼라 서브쿼리 ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- 메인 결과 행마다 실행 (입력값별 캐싱 있음)&lt;br /&gt;
SELECT o.order_no,&lt;br /&gt;
       (SELECT c.cust_nm FROM tb_customer c WHERE c.cust_no = o.cust_no) AS cust_nm&lt;br /&gt;
  FROM tb_order o&lt;br /&gt;
 WHERE o.order_dt &amp;gt;= TRUNC(SYSDATE);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* 입력값 종류가 &amp;#039;&amp;#039;&amp;#039;적으면&amp;#039;&amp;#039;&amp;#039; 캐싱 효과로 빠르다 (예: 코드명 조회).&lt;br /&gt;
* 입력값 종류가 &amp;#039;&amp;#039;&amp;#039;많고&amp;#039;&amp;#039;&amp;#039; 메인 결과가 대량이면 → &amp;#039;&amp;#039;&amp;#039;아우터 조인&amp;#039;&amp;#039;&amp;#039;으로 바꾸고 Hash Join 검토&lt;br /&gt;
* 12c+ 옵티마이저는 스칼라 서브쿼리를 조인으로 자동 변환(Scalar Subquery Unnesting)하기도 한다.&lt;br /&gt;
&lt;br /&gt;
=== 6.4 뷰 병합과 조건 푸시다운 ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#e8f6f2;&amp;quot;&lt;br /&gt;
! 변환 !! 의미 !! 제어&lt;br /&gt;
|-&lt;br /&gt;
| View Merging || 인라인 뷰를 메인 쿼리와 합쳐 하나로 최적화 || &amp;lt;code&amp;gt;MERGE&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;NO_MERGE&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Predicate Pushing || 메인 쿼리 조건을 뷰 안으로 밀어 넣음 || &amp;lt;code&amp;gt;PUSH_PRED&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;NO_PUSH_PRED&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Join Elimination || FK 관계상 불필요한 조인 제거 || &amp;lt;code&amp;gt;NO_ELIMINATE_JOIN&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| OR-Expansion || OR 조건을 UNION ALL 형태로 분리 || &amp;lt;code&amp;gt;OR_EXPAND&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;NO_OR_EXPANSION&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
* GROUP BY·DISTINCT·ROWNUM·분석 함수가 있는 뷰는 병합이 제한된다. 실행계획에 &amp;lt;code&amp;gt;VIEW&amp;lt;/code&amp;gt;가 남아 있으면 병합되지 않은 것이다.&lt;br /&gt;
&lt;br /&gt;
== 7. 아우터 조인 ==&lt;br /&gt;
* 아우터 조인은 &amp;#039;&amp;#039;&amp;#039;기준 테이블(보존되는 쪽)&amp;#039;&amp;#039;&amp;#039;이 Outer가 되어야 한다는 제약이 있었다.&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;NL 아우터 조인&amp;#039;&amp;#039;&amp;#039; — 반드시 기준 테이블이 Driving&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Hash 아우터 조인&amp;#039;&amp;#039;&amp;#039; — 10g+ &amp;lt;code&amp;gt;HASH JOIN RIGHT OUTER&amp;lt;/code&amp;gt;로 &amp;#039;&amp;#039;&amp;#039;작은 Inner 쪽을 Build&amp;#039;&amp;#039;&amp;#039;로 사용 가능 (&amp;lt;code&amp;gt;SWAP_JOIN_INPUTS&amp;lt;/code&amp;gt;)&lt;br /&gt;
* 아우터 조인 대상 테이블의 조건은 &amp;lt;code&amp;gt;ON&amp;lt;/code&amp;gt; 절에 둘 것인가, &amp;lt;code&amp;gt;WHERE&amp;lt;/code&amp;gt; 절에 둘 것인가에 따라 &amp;#039;&amp;#039;&amp;#039;결과가 달라진다&amp;#039;&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
-- ON 절: 주문이 없는 고객도 나오고, 주문은 &amp;#039;10&amp;#039; 상태만 붙음&lt;br /&gt;
SELECT c.cust_no, o.order_no&lt;br /&gt;
  FROM tb_customer c LEFT JOIN tb_order o&lt;br /&gt;
    ON o.cust_no = c.cust_no AND o.stat_cd = &amp;#039;10&amp;#039;;&lt;br /&gt;
&lt;br /&gt;
-- WHERE 절: o.stat_cd = &amp;#039;10&amp;#039; 조건으로 NULL 행이 제거되어 사실상 이너 조인&lt;br /&gt;
SELECT c.cust_no, o.order_no&lt;br /&gt;
  FROM tb_customer c LEFT JOIN tb_order o ON o.cust_no = c.cust_no&lt;br /&gt;
 WHERE o.stat_cd = &amp;#039;10&amp;#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 8. 적응적 조인 (Adaptive Plan, 12c+) ==&lt;br /&gt;
* 실행 중 &amp;lt;code&amp;gt;STATISTICS COLLECTOR&amp;lt;/code&amp;gt;가 실제 행 수를 세어, 임계값을 넘으면 &amp;#039;&amp;#039;&amp;#039;NL → Hash&amp;#039;&amp;#039;&amp;#039;로 전환한다.&lt;br /&gt;
* 확인: &amp;lt;code&amp;gt;DBMS_XPLAN.DISPLAY_CURSOR(…, &amp;#039;ALLSTATS LAST +ADAPTIVE&amp;#039;)&amp;lt;/code&amp;gt; — 비활성 단계는 &amp;#039;&amp;#039;&amp;#039;-&amp;#039;&amp;#039;&amp;#039; 표시&lt;br /&gt;
* Note 섹션의 &amp;lt;code&amp;gt;this is an adaptive plan&amp;lt;/code&amp;gt; 문구로 확인&lt;br /&gt;
* 관련 파라미터 (19c): &amp;lt;code&amp;gt;OPTIMIZER_ADAPTIVE_PLANS&amp;lt;/code&amp;gt; (기본 TRUE), &amp;lt;code&amp;gt;OPTIMIZER_ADAPTIVE_STATISTICS&amp;lt;/code&amp;gt; (기본 FALSE)&lt;br /&gt;
&lt;br /&gt;
== 9. 조인 튜닝 체크리스트 ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;border:1px solid #cfe9e2;background:#f6fcfa;border-radius:10px;padding:14px 22px;line-height:1.9;&amp;quot;&amp;gt;&lt;br /&gt;
□ Driving 집합이 &amp;#039;&amp;#039;&amp;#039;가장 적은 건수&amp;#039;&amp;#039;&amp;#039;로 시작하는가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ NL Inner 쪽 &amp;#039;&amp;#039;&amp;#039;조인 컬럼 + 필터 컬럼&amp;#039;&amp;#039;&amp;#039; 결합 인덱스가 있는가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ NL Inner &amp;#039;&amp;#039;&amp;#039;Starts&amp;#039;&amp;#039;&amp;#039;가 수만 이상이면 Hash Join과 비교했는가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ Hash Join의 &amp;#039;&amp;#039;&amp;#039;Build 집합&amp;#039;&amp;#039;&amp;#039;이 작은 쪽인가, Temp를 쓰지 않는가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ 조인 순서상 &amp;#039;&amp;#039;&amp;#039;건수가 빨리 줄어드는&amp;#039;&amp;#039;&amp;#039; 순서인가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ &amp;lt;code&amp;gt;MERGE JOIN CARTESIAN&amp;lt;/code&amp;gt;이 의도된 것인가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ 서브쿼리가 FILTER 방식이라면 입력값 캐싱 효과가 있는가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ &amp;lt;code&amp;gt;NOT IN&amp;lt;/code&amp;gt; 사용 시 NULL 가능성을 확인했는가&amp;lt;br/&amp;gt;&lt;br /&gt;
□ 아우터 조인 조건 위치(ON / WHERE)가 의도와 일치하는가&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 10. 실습 과제 ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border:1px solid #cfe9e2;border-radius:10px;padding:12px 18px;margin-bottom:12px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;과제 1.&amp;#039;&amp;#039;&amp;#039; 3.4절의 두 SQL을 실행해 Buffers와 A-Time을 비교하고, VIP 조건을 특정 고객 1명으로 바꿨을 때 결과가 어떻게 뒤바뀌는지 확인하라.&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;margin-top:8px;color:#3d5a52;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;기대 결과&amp;#039;&amp;#039;&amp;#039; 5,000명 → Hash 유리, 1명 → NL이 수십 블록으로 압도적 유리. 조인 방식의 우열은 &amp;#039;&amp;#039;&amp;#039;건수&amp;#039;&amp;#039;&amp;#039;가 결정한다.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border:1px solid #cfe9e2;border-radius:10px;padding:12px 18px;margin-bottom:12px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;과제 2.&amp;#039;&amp;#039;&amp;#039; EXISTS 서브쿼리를 &amp;lt;code&amp;gt;NO_UNNEST&amp;lt;/code&amp;gt;(FILTER)와 &amp;lt;code&amp;gt;UNNEST HASH_SJ&amp;lt;/code&amp;gt;로 각각 실행해 Starts와 Buffers를 비교하라. 메인 집합을 코드성 값(입력값 종류 10개)으로 바꿔 다시 비교하라.&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;margin-top:8px;color:#3d5a52;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;기대 결과&amp;#039;&amp;#039;&amp;#039; 입력값 종류가 많으면 Semi Join이 유리하고, 종류가 적으면 FILTER 캐싱으로 서브쿼리 실제 수행 횟수가 크게 줄어 FILTER도 충분히 빠르다.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; style=&amp;quot;border:1px solid #cfe9e2;border-radius:10px;padding:12px 18px;margin-bottom:12px;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;과제 3.&amp;#039;&amp;#039;&amp;#039; 4개 테이블 조인 SQL(5.2절)에서 가능한 Driving 테이블 후보 3개로 각각 실행하여 단계별 A-Rows 흐름표를 작성하라.&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;margin-top:8px;color:#3d5a52;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;작성 양식&amp;#039;&amp;#039;&amp;#039; 순서 / 1단계 A-Rows / 2단계 A-Rows / 3단계 A-Rows / 최종 / 총 Buffers. 중간 단계 A-Rows의 &amp;#039;&amp;#039;&amp;#039;합이 가장 작은&amp;#039;&amp;#039;&amp;#039; 순서가 대개 가장 효율적이다.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;margin-top:30px;padding:14px 20px;border-top:3px solid #0b4d40;background:#f3faf8;border-radius:0 0 10px 10px;font-size:13px;color:#3d5a52;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;이전&amp;#039;&amp;#039;&amp;#039; ← [[인덱스 튜닝 심화]] · [[실행계획 읽기 실습]] &amp;amp;nbsp;|&amp;amp;nbsp; &amp;#039;&amp;#039;&amp;#039;다음&amp;#039;&amp;#039;&amp;#039; → [[AWR 리포트 분석]] &amp;amp;nbsp;|&amp;amp;nbsp; &amp;#039;&amp;#039;&amp;#039;처음으로&amp;#039;&amp;#039;&amp;#039; → [[SQL 튜닝 입문]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[분류:SQL 튜닝]]&lt;br /&gt;
[[분류:Oracle]]&lt;br /&gt;
[[분류:조인]]&lt;/div&gt;</summary>
		<author><name>Dbstudy</name></author>
	</entry>
</feed>