<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>index on blog.p</title><link>https://pevenc12.github.io/tags/index/</link><description>Recent content in index on blog.p</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><copyright>© Peven</copyright><lastBuildDate>Tue, 03 May 2022 23:20:11 +0800</lastBuildDate><atom:link href="https://pevenc12.github.io/tags/index/index.xml" rel="self" type="application/rss+xml"/><item><title>不要過度 Indexing，看看這個反例</title><link>https://pevenc12.github.io/posts/dont-over-index/</link><pubDate>Tue, 03 May 2022 23:20:11 +0800</pubDate><guid>https://pevenc12.github.io/posts/dont-over-index/</guid><description>本文的舉例取自 PostgreSQL Optimizer Methodology 內容主要在 PostgreSQL 的 Query Planner 如何最佳化以及其遇到的痛點，值得一看。
文中提到 PostgreSQL 對於 row-count estimate 有改善的空間時，提到了以下範例：
SELECT * FROM foo WHERE a = 1 ORDER BY b LIMIT 1; 假設資料庫已經對 a 和 b 都分別做 indexing 的話，Query Planner 可能會產出以下兩種 Plan：
利用 index scan 去找出 a = 1 的 tuples，再一一比較找出含最小值 b 的 tuple 利用 index scan 依照 b 的大小順序一一把 tuples 拉出來看，再找含 a = 1 的 tuple 如果這個 table 只有幾個 tuples 的 a 值等於 1 的話，那就很適合使用第一個方法，只需要幾次的 random access 即可找到所求。但是，如果有大量的 tuples 的 a 值為 1 的話，會因為 random access 的次數過多而導致效能變差，反而方法二可能會好一些。</description></item><item><title>PostgreSQL：淺入淺出 EXPLAIN（上）</title><link>https://pevenc12.github.io/posts/postgresql-explain-explained-scan/</link><pubDate>Tue, 29 Jun 2021 18:15:20 +0800</pubDate><guid>https://pevenc12.github.io/posts/postgresql-explain-explained-scan/</guid><description>前言 利用 EXPLAIN 指令對 SQL 進行效能分析相當的重要。除了確認資料庫內的索引（index）是否如預期被使用之外，再加上 ANALYZE ，更可以得到確切的執行流程與時間，由此來分析系統找出瓶頸。本文會先介紹 PostgreSQL 的三種掃描（SCAN）行為以及解說部分 Query Plan，下篇會再介紹各種聯合（JOIN）行為。
Scan Sequence Scan 會依序掃描所有硬碟中的 pages ，並找出符合查詢條件的資料（rows，行）。雖然聽起來很慢，但是在掃描的過程中會使用順序 I/O （Sequence I/O）而不是隨機 I/O （Random I/O），來提高速度。順序 I/O 的速度不管是在 HDD 上或是 SSD 上都明顯較快。
通常要避免資料庫進行全表查詢時，會加入索引來加快查詢的速度，此時就適用第二種查詢方式。
Index Scan 過程可以分為下列兩個步驟：
到索引產生的 B-Tree 中去找出符合查詢條件的鍵值對（key-value pairs），如圖一。 圖一。這張表已經以 so 欄位建立索引。以 SELECT &amp;hellip; FROM &amp;hellip; WHERE so &amp;gt; 250; 這句 SQL 為例。圖中的 page number 與 offset （0~7）為了方便理解而做了簡化。 在 B-Tree 中，資料儲存的格式為鍵值對。其中鍵（key）為建立索引時所使用的欄位資料。鍵經過排序之後，儲存在 B-Tree 中，因此可以快速地被找到。而值（key）則為該筆完整資料所在的位置，類似一個指標，指向某個 page （包含 page number 以及 offset）。 拿到鍵值對後，透過 page number 與 offset 去找出該 page 與上面的完整資料（rows）。 假如有多個查詢條件，並且都有建立 B-Tree 的話，就會反覆進行步驟一與步驟二。其中因為步驟二使用的是隨機 I/O ，如果執行太多次就會造成效能低落甚至不如使用 Sequence Scan 。</description></item></channel></rss>