Project

mat_views

0.0
No release in over 3 years
There's a lot of open issues
A mountable Rails engine to track, define, refresh, and monitor Postgres materialized views.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
 Dependencies

Runtime

>= 7.1, < 9.0
 Project Readme

rails_materialized_views (mat_views)

Gem CI Maintainability Code Coverage License PostgreSQL

A Rails engine to define, create, refresh, and delete PostgreSQL materialized views with clean APIs, background jobs, observability, and CLI tasks. Built for high availability and repeatable ops.


âš¡ Why materialized views? Real numbers

On a ~50k-row dataset, reading from pre-aggregated materialized views turns heavy joins into double-digit to triple-digit speedups compared to running the raw SQL each time.

All features are designed to be production-ready with following principles

  • High availability: MVs are created and refreshed in the background, ensuring minimal downtime.
  • Repeatable operations: Clear APIs and CLI tasks for consistent behavior.
  • Observability: Track runs, errors, and performance metrics.
  • Rails-native: Integrates seamlessly with Active Job, Rails logger, and error handling.
  • Extensible: Supports multiple job adapters (ActiveJob, Sidekiq, Resque) and can be customized for specific needs.
  • Security: Contributions to security are encouraged, with a dedicated policy for reporting vulnerabilities.
  • Community-driven: Contributions are welcome, with a CLA to ensure legal clarity.
  • All features are free and open source under the MIT license. There is no other version or paid tier.

Sample run (5 iterations)

With 50,000 rows

view iterations baseline(ms) min|avg|max mv(ms) min|avg|max speedup_avg
mv_user_accounts 5 16 | 31 | 74 1 | 2 | 5 15.5
mv_user_accounts_events 5 70 | 78 | 108 1 | 1 | 2 78.0
mv_user_activity 5 159 | 161 | 165 1 | 1 | 2 161.0
mv_user 5 1 | 1 | 2 1 | 2 | 7 0.5

Stability check (100 iterations)

With 50,000 rows

view iterations baseline(ms) min|avg|max mv(ms) min|avg|max speedup_avg
mv_user_accounts 100 15 | 17 | 69 1 | 1 | 20 17.0
mv_user_accounts_events 100 70 | 70 | 73 1 | 1 | 3 70.0
mv_user_activity 100 158 | 161 | 242 1 | 1 | 2 161.0
mv_user 100 1 | 1 | 1 1 | 1 | 2 0.5

Takeaways

  • Multi-table aggregates shine: ~70× (accounts+events), ~161× (full activity).
  • Single-table scans: little/no benefit; use normal indexes or caching.
  • Materialize expensive joins/aggregations you read often.
  • PostgreSQL
    • Materialized views (MVs) make it faster for complex queries, especially those involving expensive joins or aggregations.
    • MVs are not a silver bullet for all queries; use them when they fit the use case.
    • If you have a slow query with poor performance, MVs might help you speed it up significantly.
    • MVs are not a replacement for proper indexing and query optimization.
    • Read more about PostgreSQL materialized views.

Features

  • DB definitions: SQL, strategy, unique index columns, dependencies
  • Create / Refresh / Delete services & jobs (uniform responses)
  • Refresh strategies: regular, concurrent (needs unique index), swap
  • CLI: Rake tasks for create/refresh/delete by name, id, or all (with confirm)
  • Observability: run tracking tables for create/refresh/delete
  • Rails-native: Active Job, Rails.logger, clear error reporting

Install (engine)

# Gemfile
gem 'mat_views'
bundle install
bin/rails g mat_views:install
bin/rails db:migrate

Init:

# config/initializers/mat_views.rb
MatViews.configure do |c|
  c.job_queue = :default # default queue for background jobs
  c.job_adapter = :active_job # (default), :sidekiq, :resque
end

Job adapter (enqueue)

All enqueues go through the adapter — it does not guess backends; it uses what you configured:

MatViews::Jobs::Adapter.enqueue(
  MatViews::RefreshViewJob,
  queue: MatViews.configuration.job_queue,
  args:  [definition_id, :estimated]
)
  • Supported backends: ActiveJob, Sidekiq, Resque (more welcome).
  • Configure your backend as usual; the adapter delegates accordingly.

CLI (Rake tasks)

# Create
bundle exec rake mat_views:create_by_name\[VIEW_NAME,force,--yes]
bundle exec rake mat_views:create_by_id\[ID,force,--yes]
bundle exec rake mat_views:create_all\[force,--yes]

# Refresh
bundle exec rake mat_views:refresh_by_name\[VIEW_NAME,row_count_strategy,--yes]
bundle exec rake mat_views:refresh_by_id\[ID,row_count_strategy,--yes]
bundle exec rake mat_views:refresh_all\[row_count_strategy,--yes]

# Delete
bundle exec rake mat_views:delete_by_name\[VIEW_NAME,cascade,--yes]
bundle exec rake mat_views:delete_by_id\[ID,cascade,--yes]
bundle exec rake mat_views:delete_all\[cascade,--yes]

Demo app

See mat_views_demo/ for seeds, MV definitions, and reproducible benchmarks (not shipped with the gem).


Contributing, Security, Conduct


Professional support

Need help with Rails Materialized Views? We offer professional support and custom development services. Contact us at sales@codevedas.com for inquiries.

License

MIT © Codevedas Inc.