Materialized view

구체화 뷰

Store a query result for fast reads, then refresh it to reflect source changes.

···
html
<div class="demo"><div class="head"><b>MATERIALIZED VIEW</b><span>orders count</span></div><div class="stage viewcompare"><div class="metric"><span>source</span><strong id="sourceCount">2</strong><div class="bars"><i></i><i></i><i class="extra" id="newOrder"></i></div></div><div class="metric"><span>stored view</span><strong id="viewCount">2</strong><div class="bars"><i></i><i></i><i class="extra" id="refreshed"></i></div></div></div><div class="foot"><span id="viewstatus">both show 2</span><span>REFRESH</span></div></div>
css
*{box-sizing:border-box}.demo{width:min(96vw,820px);height:min(94vh,350px);padding:clamp(8px,2vmin,18px);border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--fg);display:flex;flex-direction:column;gap:clamp(5px,1.5vmin,12px);font:600 clamp(12px,3.5vmin,15px)/1.25 var(--font-sans),sans-serif;overflow:hidden}.head,.foot,.row{display:flex;justify-content:space-between;align-items:center;gap:8px}.head b{color:var(--accent)}.head span,.foot,.muted{color:var(--muted)}.stage{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;gap:8px}.cell,.pill{border:1px solid var(--line);border-radius:8px;background:var(--bg);padding:clamp(4px,1.2vmin,9px);text-align:center}.pill{border-radius:999px}.on{border-color:var(--accent)!important;background:color-mix(in srgb,var(--accent) 17%,var(--surface))!important;color:var(--fg)!important}.bad{border-color:#e16a5d!important;background:color-mix(in srgb,#e16a5d 18%,var(--surface))!important}.foot{font-size:clamp(12px,3vmin,14px)}.viewcompare{justify-content:space-around}.metric{min-width:37%;display:grid;gap:6px;text-align:center}.metric span{color:var(--muted)}.metric strong{font:700 clamp(22px,7vmin,36px) ui-monospace,monospace;color:var(--accent)}.bars{display:flex;gap:5px;justify-content:center}.bars i{width:clamp(15px,4vmin,24px);height:clamp(23px,6vmin,36px);background:var(--accent);border-radius:3px}.bars .extra{opacity:.13;transition:opacity .3s}.bars .extra.on{opacity:1}
js
let n=0;function tick(){document.getElementById('sourceCount').textContent=n?3:2;document.getElementById('viewCount').textContent=n===2?3:2;document.getElementById('newOrder').classList.toggle('on',n>0);document.getElementById('refreshed').classList.toggle('on',n===2);document.getElementById('viewstatus').textContent=['both show 2','source changed · view stale','REFRESH · view shows 3'][n];n=(n+1)%3}tick();const t=setInterval(tick,950);document.querySelector('.demo').onclick=()=>{clearInterval(t);tick()}

A materialized view stores the result of a query. It avoids recomputing expensive aggregates on each read, but source changes do not appear until the view is refreshed.

The demo changes the order count from two to three while the view still shows two, then refreshes it to three. Choose a refresh cost and staleness window the workload can tolerate.

When to use

Use it for repeatedly read, expensive aggregates when some staleness is acceptable.

Open as page ↗