Skill

Audit SQL queries for cost and performance issues

Static SQL analyzer that audits queries for 20 cost and performance anti-patterns, scores warehouse health 0-100, and outputs a prioritized fix plan for

Works with bigquerysnowflakeredshiftpostgresclaude

Maintainer of this project? Claim this page to edit the listing.


18
Spark score
out of 100
Updated last month
Version 1.0.0

Add to Favorites

Why it matters

Automatically review warehouse SQL queries for the 22 most expensive anti-patterns-cross joins, SELECT *, missing partition filters, non-sargable predicates-and generate a prioritized cost-reduction plan with estimated savings, replacing hour-long manual reviews with millisecond static analysis.

Outcomes

What it gets done

01

Score queries 0-100 and flag critical patterns like CROSS JOINs that turn $0.02 queries into $200 bills

02

Detect non-sargable predicates (LIKE '%term', LOWER(col)) that defeat indexes and force full scans

03

Identify missing WHERE clauses, partition filters, and SELECT * on wide tables that waste 30-90% of bytes scanned

04

Output prioritized findings with why/fix explanations and estimated savings for BigQuery, Snowflake, Redshift, and Postgres

Install

Add it to your toolbox

Run in your project directory:

curl -fsSL https://spark.entire.vc/get/ag-sql-sentinel | bash

Overview

Sql Sentinel

A static SQL analyzer that catches 20 cost and performance anti-patterns across BigQuery, Snowflake, Redshift, and Postgres, scoring query health 0-100 and delivering a prioritized fix plan. Use when reviewing queries before production, investigating slow queries or high warehouse bills, or running FinOps cost-reduction initiatives. Do not use as a substitute for query-plan analysis or billing data.

What it does

sql-sentinel is a static-analysis skill that audits SQL for the cost and performance anti-patterns that dominate warehouse bills - SELECT *, full-table scans, non-sargable predicates, Cartesian joins, the NOT IN NULL trap, and 15 more. It scores warehouse query health 0-100 (A-F) and outputs a prioritized cost-reduction plan, each finding with a why, a concrete fix, and an estimated savings. The engine splits a SQL script into statements (honoring quotes and comments), runs 20 rules over each statement, scores health 0-100 weighted by severity (critical 25, high 12, medium 5, low 1), and returns a prioritized cost-reduction plan.

When to use - and when NOT to

Use sql-sentinel when you write or review a query for BigQuery, Snowflake, Redshift, Postgres, or Spark SQL; when you ask "why is this query so slow?" or "why is my warehouse bill so high?"; when you are about to promote a dashboard query or dbt model to production; when a data engineer wants a second pair of eyes before a code review or a cost-optimization sweep; or when a team is running a "reduce cloud spend" or FinOps initiative.

Do NOT use this as a substitute for query-plan analysis or billing data. This is a static analyzer that finds anti-patterns in the text of SQL; it does not read query plans, row counts, or billing. A flagged query on a 100-row table is cheap; the same query on a billion-row table is the problem the rule exists to prevent.

Inputs and outputs

You provide a SQL script as a file path or string. You receive a report object containing a health score (0-100), a letter grade (A-F), and a prioritized plan - an array of findings sorted by severity, each with a rule ID, severity level, explanation of why it costs money, and a concrete fix.

git clone https://github.com/takeaseatventure/sql-sentinel.git
cd sql-sentinel
git checkout <reviewed-commit-or-tag>
node scripts/sql-sentinel.js path/to/query.sql

Programmatic usage:

const { auditSql } = require('./scripts/sql-sentinel');
const report = auditSql(yourSqlString, { dialect: 'bigquery' });
console.log(report.healthScore);      // 0-100
console.log(report.grade);            // 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
console.log(report.prioritizedPlan);  // array, worst findings first

For example, a messy dashboard query with comma-joins, SELECT *, and NOT IN scores 17/100 (grade F) and flags 7 findings. A clean, sargable query scores 90+/100 (grade A) with no findings.

Integrations

Works across BigQuery, Snowflake, Redshift, and Postgres. Built for analytics engineers using dbt and Looker, and data platform teams running FinOps or "reduce cloud spend" initiatives. Zero dependencies, MIT licensed.

Who it's for

Analytics engineers (dbt, Looker), data platform teams running FinOps or "reduce cloud spend" initiatives, and anyone reviewing a SQL pull request before it hits production. The 20-rule set (ruleset v1.0.0) catches critical issues like CROSS JOIN and comma-joins, high-severity patterns like SELECT * and leading-wildcard LIKE, medium-severity issues like SELECT DISTINCT and scalar subqueries, and low-severity style problems. Run the test suite to verify each rule fires on real SQL: cd scripts && node test.js (26 tests, zero dependencies). It does not execute SQL - safe to run on any .sql file.

Source README

sql-sentinel

Overview

A static-analysis skill that audits SQL for the cost & performance anti-patterns that dominate warehouse bills - SELECT *, full-table scans, non-sargable predicates, Cartesian joins, the NOT IN NULL trap, and 15 more. It scores warehouse query health 0-100 (A-F) and outputs a prioritized cost-reduction plan, each finding with a why, a concrete fix, and an estimated savings.

Built for analytics engineers (dbt, Looker), data platform teams running FinOps / "reduce cloud spend" initiatives, and anyone reviewing a SQL pull request before it hits production. Works across BigQuery, Snowflake, Redshift, and Postgres. Zero dependencies, MIT licensed.

The executable engine and full rule set live in the source repository: https://github.com/takeaseatventure/sql-sentinel. Treat that repository as third-party executable code.

When to Use This Skill

  • A user writes or reviews a query for BigQuery, Snowflake, Redshift, Postgres, or Spark SQL.
  • A user asks "why is this query so slow?" or "why is my warehouse bill so high?"
  • A user is about to promote a dashboard query or dbt model to production.
  • A data engineer wants a second pair of eyes before a code review or a cost-optimization sweep.
  • A team is running a "reduce cloud spend" or FinOps initiative.

How It Works

The engine splits a SQL script into statements (honoring quotes and comments), runs 20 rules over each statement, scores health 0-100 weighted by severity (critical 25, high 12, medium 5, low 1), and returns a prioritized cost-reduction plan.

Step 1: Run the audit

Install or clone the source repository only after choosing a reviewed commit, tag, or release to trust. Do not run code from a mutable default branch just because this skill links to it:

git clone https://github.com/takeaseatventure/sql-sentinel.git
cd sql-sentinel
git checkout <reviewed-commit-or-tag>
node scripts/sql-sentinel.js path/to/query.sql

Or programmatically:

const { auditSql } = require('./scripts/sql-sentinel');
const report = auditSql(yourSqlString, { dialect: 'bigquery' });
console.log(report.healthScore);      // 0-100
console.log(report.grade);            // 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
console.log(report.prioritizedPlan);  // array, worst findings first

Step 2: Read the prioritized plan

The output leads with critical findings (Cartesian joins, mass DELETE) and descends to low-severity style issues. Each finding explains why it costs money and how to fix it.

Examples

Example 1: A messy dashboard query

SELECT DISTINCT *
FROM user_events, raw_logs
WHERE LOWER(event_name) LIKE '%signup%'
  AND user_id NOT IN (SELECT id FROM deleted_users)
ORDER BY created_at;

The audit scores this 17/100 (grade F) and flags 7 findings:

  • CRITICAL: comma-join produces a Cartesian product (can turn a $0.02 query into a $200 query)
  • HIGH: SELECT * forces full column scan (30-90% wasted bytes on wide tables)
  • HIGH: leading-wildcard LIKE '%signup%' defeats indexes
  • HIGH: LOWER(event_name) defeats indexes (non-sargable)
  • HIGH: NOT IN (SELECT ...) - NULL semantics hazard
  • MEDIUM: SELECT DISTINCT dedup cost
  • MEDIUM: ORDER BY without LIMIT sorts the full result

Example 2: A clean, sargable query

-- This scores 90+/100 (grade A) — no findings
SELECT id, email, created_at
FROM users
WHERE created_at >= TIMESTAMP '2026-01-01'
  AND created_at <  TIMESTAMP '2026-02-01'
ORDER BY id
LIMIT 100;

The 20 rules (ruleset v1.0.0)

Rule Severity Catches
SQL001 high SELECT * full column scan
SQL002 critical No WHERE → full table scan
SQL003 high LIKE '%term' non-sargable
SQL004 high Function on column kills index
SQL005 critical CROSS JOIN / comma-join
SQL006 medium SELECT DISTINCT dedup cost
SQL007 medium ORDER BY without LIMIT
SQL008 high NOT IN (SELECT ...) NULL trap
SQL009 medium Implicit type cast
SQL010 low Many ORs (use IN/UNION)
SQL011 medium COUNT(DISTINCT) at scale (use HLL)
SQL012 low LIMIT without ORDER BY
SQL013 medium Scalar subquery in SELECT
SQL014 medium 5+ JOINs broadcast/spill risk
SQL015 high Fact table, no partition filter
SQL017 low String concat in SELECT
SQL018 medium Window OVER () no PARTITION
SQL020 critical DELETE/UPDATE without WHERE
SQL021 low SELECT * in EXISTS/IN
SQL022 medium UNION vs UNION ALL

Run the test suite to verify each rule fires on real SQL:

cd scripts && node test.js   # 26 tests, zero dependencies

Limitations

  • This is a static analyzer. It finds anti-patterns in the text of SQL; it does not read query plans, row counts, or billing. A flagged query on a 100-row table is cheap; the same query on a billion-row table is the problem the rule exists to prevent.
  • The fact-table heuristic (SQL015) keys off table names (*_events, *_log) and is advisory, not definitive.
  • It does not execute SQL - safe to run on any .sql file.

FAQ

Common questions

Discussion

Questions & comments · 0

Sign In Sign in to leave a comment.