<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mohammad Atif</title>
    <description>The latest articles on Forem by Mohammad Atif (@mohammad-atif).</description>
    <link>https://forem.com/mohammad-atif</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3673886%2F64cc74c9-850d-4477-8cbd-1303d76fdbeb.JPG</url>
      <title>Forem: Mohammad Atif</title>
      <link>https://forem.com/mohammad-atif</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mohammad-atif"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Mohammad Atif</dc:creator>
      <pubDate>Sat, 28 Feb 2026 19:22:04 +0000</pubDate>
      <link>https://forem.com/mohammad-atif/-5ddp</link>
      <guid>https://forem.com/mohammad-atif/-5ddp</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/mohammad-atif" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3673886%2F64cc74c9-850d-4477-8cbd-1303d76fdbeb.JPG" alt="mohammad-atif"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/mohammad-atif/clustered-vs-non-clustered-index-in-sqlcomplete-guide-with-examples-14gm" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Clustered vs Non-Clustered Index in SQL(Complete Guide with Examples)&lt;/h2&gt;
      &lt;h3&gt;Mohammad Atif ・ Feb 28&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#database&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#sql&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#clusteredvsnonclusteredindex&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#postgres&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>database</category>
      <category>sql</category>
      <category>clusteredvsnonclusteredindex</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Clustered vs Non-Clustered Index in SQL(Complete Guide with Examples)</title>
      <dc:creator>Mohammad Atif</dc:creator>
      <pubDate>Sat, 28 Feb 2026 18:56:53 +0000</pubDate>
      <link>https://forem.com/mohammad-atif/clustered-vs-non-clustered-index-in-sqlcomplete-guide-with-examples-14gm</link>
      <guid>https://forem.com/mohammad-atif/clustered-vs-non-clustered-index-in-sqlcomplete-guide-with-examples-14gm</guid>
      <description>&lt;h2&gt;
  
  
  1. Introduction: Why Do We Need Indexes?
&lt;/h2&gt;

&lt;p&gt;Speed and efficiency are key when it comes to querying a database. An index is a data structure that acts as a guide for your database, giving you quick access to a particular data set to speed up your queries significantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;To understand indexes, let’s consider a couple of analogies.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Book:
You don’t want to go through each page of a book to find a particular chapter or data; instead, you look in the back of the book to find that chapter quickly.&lt;/li&gt;
&lt;li&gt;The Hotel:
You don’t want to knock on every hotel room on every floor to find room 5001; instead, you look at a map in the lobby to quickly locate that room.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. The Foundation: Data Pages and The Heap Structure
&lt;/h2&gt;

&lt;p&gt;Before we move on to indexes, we should know how SQL stores data logically as well as physically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data Pages:
&lt;/h3&gt;

&lt;p&gt;When you create a new table in your SQL database and start adding data to it, SQL doesn’t store data as a spreadsheet; instead, it stores data in data files on your hard disk, divided into fixed-size 8-Kilobyte blocks called “Pages.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Data Page Consists Of&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page Header: This contains metadata related to that particular page.&lt;/li&gt;
&lt;li&gt;Data Rows: This contains your actual data. The amount of data that you can store here is determined by your data size.&lt;/li&gt;
&lt;li&gt;Offset Array: This is a small internal map that quickly tracks where your data starts on that particular page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v3xgg0t9n3l1plj94mf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v3xgg0t9n3l1plj94mf.png" alt="Data Page Structure. Diagram of a SQL Server data page showing page header, multiple data rows, free space area, and offset array at the bottom indicating row positions within an 8KB page." width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Heap Structure (No Index)
&lt;/h2&gt;

&lt;p&gt;If you don't create an index on your table, your data is stored in a Heap Structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write Logic&lt;/strong&gt;: When new data is added to your table, SQL just throws it onto the next available Data Page in the order it was written. They're not sorted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foq51bia7q9kn9n0g2803.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foq51bia7q9kn9n0g2803.png" alt="Multiple Data Pages (Heap Example). Illustration of multiple unsorted SQL data pages (1:100, 1:101, 1:102, 1:103) containing customer records stored sequentially without logical ordering, representing heap storage." width="767" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Read Logic&lt;/strong&gt; (Full Table Scan): Because your data is unsorted, when you want to read a particular record, say Customer ID 14, SQL doesn't know where it is. It has to perform a Full Table Scan, reading every single Data Page until it finds your record.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-off&lt;/strong&gt;: Fast write speed (no sorting necessary), terrible read speed.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. The Clustered Index
&lt;/h2&gt;

&lt;p&gt;A Clustered Index changes everything about how your data is stored on your hard disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Physical Sorting: 
&lt;/h3&gt;

&lt;p&gt;A Clustered Index on a particular column (e.g., User_ID) causes SQL to physically sort ALL existing data pages on that column from lowest to highest.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3low2ro9h0xk1t4lcngw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3low2ro9h0xk1t4lcngw.png" alt="Sequential Data Pages Example. Illustration of four SQL Server data pages (1:100, 1:101, 1:102, 1:103) containing sequentially stored records (IDs 1–20) across multiple pages, demonstrating how rows are distributed across physical data pages in storage." width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The B-Tree Logic: 
&lt;/h3&gt;

&lt;p&gt;SQL uses a default data structure called a B-Tree (Balanced Tree) to navigate this sorted data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Root Node&lt;/strong&gt; (Top): An index page that contains a pointer to intermediate pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intermediate Nodes&lt;/strong&gt;: Index pages that contain a pointer to a particular set of data (e.g., "IDs 1-10 go left, IDs 11-20 go right").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leaf Nodes&lt;/strong&gt; (Bottom): In a Clustered Index, this is your actual Data Page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F465ew8zbcm8wp5bsdlqn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F465ew8zbcm8wp5bsdlqn.png" alt="B-Tree Hierarchical Structure. Diagram of a balanced B-Tree used in SQL indexing, showing a root node at the top, multiple intermediate nodes branching below, and leaf nodes at the bottom level representing final data access points." width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1zcn39cvhyfnlckomu2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1zcn39cvhyfnlckomu2.png" alt="Clustered Index Navigation Example. Illustration of a clustered index B-Tree where index pages (1:300, 1:200, 1:201) route value ranges (1–10, 11–20) down to sorted data pages (1:100, 1:101, 1:102, 1:103), demonstrating how SQL Server navigates through index pages to retrieve ordered records efficiently." width="800" height="634"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Characteristics&lt;/strong&gt;: Limit: You can only have ONE Clustered Index per table because your data can only be sorted in ONE way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ideal Candidate: 
&lt;/h3&gt;

&lt;p&gt;Primary Keys are perfect for Primary Keys. They are unique, and they are never updated. (Updating a clustered index column requires the database to move the row to maintain the sort order, which is very resource intensive).&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Non-Clustered Index
&lt;/h2&gt;

&lt;p&gt;A Non-Clustered Index makes reads faster but never changes the physical order of the underlying table.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Pointer Structure
&lt;/h3&gt;

&lt;p&gt;When you create a non-clustered index, SQL leaves the actual Data Pages exactly as they are, whether they are a Heap or sorted by a clustered index. It simply creates an entirely separate B-Tree structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  The B-Tree Logic
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Leaf Nodes&lt;/strong&gt;: Unlike the clustered index, these leaf nodes are Index Pages, not Data Pages. These leaf nodes are simply a list of the actual index values, along with a Row Identifier (RID) [00:17:42]. This RID is an exact address, like File ID, Page Number, and then an actual Offset, which points to where the actual row lives in the actual table.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Navigation&lt;/strong&gt;: To retrieve your actual row, SQL uses the non-clustered index B-Tree, navigates down to the leaf node, finds the RID, and then makes one "jump" to the actual Data Page to retrieve the actual row.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjeh6ri9433xjicmcowq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjjeh6ri9433xjicmcowq.png" alt="Non-Clustered Index Structure. Non-clustered index B-Tree showing index pages containing key values and row identifiers (RIDs) that point to separate data pages." width="711" height="764"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6ka3eba80ptqg2rz16g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx6ka3eba80ptqg2rz16g.png" alt="Simplified Non-Clustered Pointer Flow. Diagram illustrating how index pages reference multiple data pages via pointers, demonstrating logical separation between index structure and physical data storage." width="800" height="724"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Characteristics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limit: You may have multiple non-clustered indexes on one single table.&lt;/li&gt;
&lt;li&gt;Ideal Candidate: Columns you often use in your WHERE clause, like "Last_Name," or often use in your JOIN clause.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Direct Comparison: Clustered vs. Non-Clustered
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk1fo4nlqqas8k96kbjq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk1fo4nlqqas8k96kbjq.png" alt="Clustered vs Non-Clustered Comparison Table. Side-by-side comparison chart of clustered and non-clustered indexes highlighting definition, number of indexes allowed, read performance, write performance, storage efficiency, and use cases." width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. SQL Syntax and Implementation
&lt;/h2&gt;

&lt;p&gt;Creating indexes in SQL Server uses straightforward syntax. By default, if Primary Keys are defined, SQL automatically creates a clustered index for them and uses B-Tree as default data structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Clustered Index:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CREATE CLUSTERED INDEX idx_customers_id ON sales.customers (customer_id);&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Non-Clustered Index:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;CREATE NONCLUSTERED INDEX idx_customers_lastname ON sales.customers (last_name);&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
(Note: If you do not specify "NONCLUSTERED", SQL Server defaults to Non-Clustered.)&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;I have another post in which I have talked about how to achieve best unique identifier key for your table's cluster index for the fastest Read/Write. &lt;a href="https://dev.to/mohammad-atif/postgresql-primary-keys-why-your-uuid-choice-matters-4h96"&gt;&lt;strong&gt;Click Me&lt;/strong&gt;&lt;/a&gt; to redirect to the relevant post.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>database</category>
      <category>sql</category>
      <category>clusteredvsnonclusteredindex</category>
      <category>postgres</category>
    </item>
    <item>
      <title>PostgreSQL Primary Keys-Why Your UUID Choice Matters</title>
      <dc:creator>Mohammad Atif</dc:creator>
      <pubDate>Tue, 23 Dec 2025 04:53:46 +0000</pubDate>
      <link>https://forem.com/mohammad-atif/postgresql-primary-keys-why-your-uuid-choice-matters-4h96</link>
      <guid>https://forem.com/mohammad-atif/postgresql-primary-keys-why-your-uuid-choice-matters-4h96</guid>
      <description>&lt;h2&gt;
  
  
  Before diving in
&lt;/h2&gt;

&lt;p&gt;So before diving into the topic there are some base information that we need to be aware of.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. PostgreSQL indexes
&lt;/h2&gt;

&lt;p&gt;PostgreSQL has various types of indexes and different indexes have different strengths and weaknesses. PostgreSQL uses &lt;strong&gt;B-Tree index&lt;/strong&gt; for indexing the primary key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; PRIMARY KEY and UNIQUE constraints create an index by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. What is a B-Tree?
&lt;/h2&gt;

&lt;p&gt;The term “B-Tree” is short for “balanced tree” indicating that the distance between each node and the root is consistent across all levels. Furthermore, the root and its parent nodes can have more than two children, which effectively minimizes the depth of the tree, enhancing search efficiency.&lt;/p&gt;

&lt;p&gt;Let’s see the main aspects about B-Trees:&lt;/p&gt;

&lt;h3&gt;
  
  
  Main characteristics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node Flexibility:&lt;/strong&gt; Nodes can have more than two children, typically varying from a minimum of two to a maximum defined by the tree order (M). &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Height Management:&lt;/strong&gt; Automatically adjusts to maintain a height of logM N, optimizing search operations. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sorting Order:&lt;/strong&gt; Maintains data in sorted order, ensuring the smallest values are on the left and the largest on the right. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uniformity and Efficiency:&lt;/strong&gt; All leaf nodes are at the same level to ensure efficiency and consistency, and there are no empty subtrees above the leaf nodes. &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What it is best at
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Totally ordered data&lt;/li&gt;
&lt;li&gt;Equality, range, sorting&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Supports =, &amp;lt;, &amp;lt;=, &amp;gt;, &amp;gt;=&lt;/li&gt;
&lt;li&gt;Supports ORDER BY natively&lt;/li&gt;
&lt;li&gt;Supports UNIQUE / PRIMARY KEY&lt;/li&gt;
&lt;li&gt;Supports multi-column indexes&lt;/li&gt;
&lt;li&gt;Can do index-only scans&lt;/li&gt;
&lt;li&gt;Backward scan supported&lt;/li&gt;
&lt;li&gt;Very stable performance&lt;/li&gt;
&lt;li&gt;Balanced tree → predictable depth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Inefficient for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full-text search&lt;/li&gt;
&lt;li&gt;Arrays&lt;/li&gt;
&lt;li&gt;JSON path queries&lt;/li&gt;
&lt;li&gt;Geometric data&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Not useful for highly unselective columns (e.g. boolean)&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance characteristics
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lookup:&lt;/strong&gt; O(log N) &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Range scan:&lt;/strong&gt; extremely efficient &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insert cost:&lt;/strong&gt; moderate (page splits) &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update cost:&lt;/strong&gt; moderate &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; medium &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Typical use cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Primary keys&lt;/li&gt;
&lt;li&gt;Foreign keys&lt;/li&gt;
&lt;li&gt;Dates &amp;amp; timestamps&lt;/li&gt;
&lt;li&gt;Numeric ranges&lt;/li&gt;
&lt;li&gt;ORDER BY + LIMIT queries&lt;/li&gt;
&lt;li&gt;Pagination&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Important observation
&lt;/h2&gt;

&lt;p&gt;Notice any pattern — if we somehow get data that is already sorted we could use that to our advantage as we could predict how the data would be stored thus, performing quick lookups along with other features such as equality, range, and other discussed above.&lt;/p&gt;

&lt;p&gt;But at the same time if the data stored has no correlation making these other important functionalities go to waste.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Types of unique identifiers and their features
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2spme0lxuzhgdwh8h3z0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2spme0lxuzhgdwh8h3z0.png" alt="Types of unique identifiers and their features" width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So if we use a time based UUID we can still avoid collision while leveraging full potential of B-Tree indexing.&lt;/p&gt;

&lt;p&gt;Since every newly created UUID would be greater than the previous UUID it would be stored in the rightmost node of the tree which PostgreSQL optimizes for us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes in practice?
&lt;/h2&gt;

&lt;p&gt;Now for lookups both of them would give the result in nearly same time with nearly same index size but the magic happens next.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search object created at a particular day and time from index without using another index on createdAt key. &lt;/li&gt;
&lt;li&gt;If we need to debloat our data set due to storage cost we can even remove createdAt key.&lt;/li&gt;
&lt;li&gt;Search objects with time based range.&lt;/li&gt;
&lt;li&gt;Since all new UUIDs are inserted in rightmost node, insert cost is reduced.&lt;/li&gt;
&lt;li&gt;Improved VACUUM and bloat behavior.&lt;/li&gt;
&lt;li&gt;More predictable pagination.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When IDs are time-ordered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
  WHERE id &amp;gt; last_seen_id

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;In simpler terms time based UUIDs transforms a liability into a useful performance commodity.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>backend</category>
      <category>databaseindexing</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
