High Leverage Rails
Introduction
Introduction to this course
Why use Ruby on Rails
Why use SQLite
Ruby on Rails + SQLite
Powering Your App with SQLite
Creating tables
Timestamps
Column types
Typeof
Ruby types
Creating table introduction
Creating table advanced
Inserting data
Updating data
Upserting data
Reading data
Virtual columns
Enums
Introduction to JSON
Indexing JSON
JSON table functions
Building a Modern Rails Application
Creating a new Rails application
Installing Solid Queue
Installing Solid Cache
Installing Solid Cable
Dockerfile
Application overview
Authentication
Base styles
Registration
Scaffolding posts
Polishing posts
Scaffolding comments
Polishing comments
Polishing models
Polishing controllers
Creating new post
Updating post
Reviewing MVP
Tagging posts
Custom tags
Friendly URLs
Full text search
Deploying & Operating Your App
Backups
Check Litestream locally
Verifying backups
Deployment options
Deploying with Hatchbox
Deployment constraints
Vertical scaling
Database access
Migrations
Locked video

Please purchase the course to watch this video.

Video thumbnail
Powering Your App with SQLite
Indexing JSON

Full Course

$
129
$179
USD, one-time fee
This course came at the perfect time. I’ve recently gotten back into Rails after an 18-year hiatus, and this was a perfect refresher and shows just how much you can accomplish with Rails right out of the box.
Garrett Winder
Garrett Winder

Rails hosting made simple

Deploy apps to servers that you own and control.

Move fast and fix things

Application monitoring that helps developers get it done.

Summary

Optimize JSON queries in SQLite by using stored virtual columns to extract and index specific JSON values. This approach enables efficient indexed searches, reducing full-table scans and improving database performance. Learn how to leverage Active Record and SQLite to handle JSON data effectively in Rails applications.

Video Transcript

When working with JSON columns, one of the most important considerations is access patterns. If our posts table contains millions of rows, certain search queries—especially those not using an index—can become performance bottlenecks.

Although SQLite does not support generic indexing of entire JSON columns, we can create specific indexes for subsets of JSON data that match our expected access patterns. Let’s explore how to do this.

Using Virtual Columns to Index JSON Data

Jumping back into our playground, we still have our posts table with a metadata JSON column. However, this time, I’ve added a virtual column for word_count.

  • This word_count column extracts the word_count value from the JSON content.
  • It is cast as an integer for proper indexing.
  • Defining it as a stored column allows us to create an index on it.

Why Use a Stored Virtual Column?

By using stored virtual columns, we can extract and index specific values inside JSON payloads, making queries much faster. Let’s examine the impact of indexing on query performance.

Comparing Query Performance: JSON Search vs. Indexed Virtual Column

  1. Searching JSON Data Without an Index

If we run a query to find posts where word_count is greater than 1,000 directly in the JSON column:

Post.where("metadata ->> '$.content.word_count' > ?", 1000).explain

This means SQLite scans the entire table, which is extremely inefficient for large datasets. If we have millions of rows, this approach can become a serious performance bottleneck.

  1. Searching Using an Indexed Virtual Column

Now, let’s run the same query using our stored virtual column:

Post.where("word_count > ?", 1000).explain

Since we created an index on word_count, SQLite uses the index instead of scanning the entire table, significantly improving query speed and efficiency.

Balancing JSON Storage and Indexed Reads

JSON columns are great for storing flexible data structures without needing multiple tables. Virtual columns allow us to extract specific values from JSON data and index them. Using indexes on frequently queried JSON values improves performance, reducing the need for full-table scans.

However, JSON columns should only be used for data that is written once and read many times. If frequent updates are required, a separate table is often the better choice, as SQLite is optimized for structured relational data.

In our final video in this module, we’ll explore how to use SQLite’s aggregate table functions with JSON to perform advanced queries efficiently.