CtrlK
BlogDocsLog inGet started
Tessl Logo

sql-insight

Translate natural language to SQL, optimize query performance, and interpret EXPLAIN plans for SQLite and PostgreSQL. Triggered when users ask to convert questions into SQL, improve slow queries, tune indexes, analyze execution plans, or mention keywords like NL2SQL, query tuning, or full table scan.

72

Quality

88%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Low

Low-risk findings worth noting

SKILL.md
Quality
Evals
Security

sql-insight

SQL query assistant — natural language to SQL translation, query optimization analysis, and EXPLAIN plan interpretation.

Capabilities

FeatureDescription
Schema ExtractionExtracts database table structure (columns, types, indexes, foreign keys, sample data) to provide context for NL→SQL
Natural Language → SQLTranslates natural language descriptions into SQL queries using schema context
Query Optimization AnalysisDetects SQL anti-patterns based on 13 rules and provides optimization suggestions
EXPLAIN InterpretationRuns EXPLAIN and interprets the query plan, identifying full table scans, missing indexes, and more

Workflow

Natural Language → SQL

  1. Use the schema command to extract the database table structure
  2. Use the schema as context to translate the user's natural language request into SQL
  3. Use the optimize command to check if the generated SQL can be improved
  4. Use the explain command to verify the query execution plan
# Step 1: Extract schema (compact mode, suitable for LLM context)
python3 scripts/sql_query_helper.py --db-path data.db schema --compact

# Step 2: Analyze SQL optimization suggestions
python3 scripts/sql_query_helper.py optimize "SELECT * FROM orders WHERE user_id = 100"

# Step 3: View EXPLAIN execution plan
python3 scripts/sql_query_helper.py --db-path data.db explain "SELECT * FROM orders WHERE user_id = 100"

Quick Start

Schema Extraction

# Extract full schema (JSON format, with sample data)
python3 scripts/sql_query_helper.py --db-path data.db schema

# Compact mode (plain text, suitable for embedding in prompts)
python3 scripts/sql_query_helper.py --db-path data.db schema --compact

# Skip data sampling
python3 scripts/sql_query_helper.py --db-path data.db schema --sample-rows 0

# PostgreSQL
python3 scripts/sql_query_helper.py --db-type postgres --dsn "host=localhost dbname=mydb user=reader" schema --compact

Query Optimization Analysis

# Analyze SQL query (no database connection required, pure rule-based detection)
python3 scripts/sql_query_helper.py optimize "SELECT * FROM orders o, users u WHERE o.user_id = u.id"

python3 scripts/sql_query_helper.py optimize "SELECT name FROM users WHERE UPPER(email) LIKE '%@GMAIL.COM'"

python3 scripts/sql_query_helper.py optimize "SELECT id, (SELECT COUNT(*) FROM orders WHERE user_id = u.id) AS order_count FROM users u"

EXPLAIN Interpretation

# SQLite EXPLAIN
python3 scripts/sql_query_helper.py --db-path data.db explain "SELECT * FROM orders WHERE user_id = 100"

# PostgreSQL EXPLAIN
python3 scripts/sql_query_helper.py --db-type postgres --dsn "host=localhost dbname=mydb" explain "SELECT * FROM orders WHERE user_id = 100"

# PostgreSQL EXPLAIN ANALYZE (actually executes the query for real-world data)
python3 scripts/sql_query_helper.py --db-type postgres --dsn "host=localhost dbname=mydb" explain --analyze "SELECT * FROM orders WHERE user_id = 100"

Detailed Usage

Global Parameters

ParameterRequiredDefaultDescription
--db-typeNosqliteDatabase type: sqlite or postgres
--db-pathFor schema/explain (SQLite)SQLite database file path
--dsnFor schema/explain (PostgreSQL)PostgreSQL connection string

Subcommands

CommandRequires DatabaseDescription
schemaYesExtract database table structure
optimize <sql>NoSQL query optimization analysis (pure rule-based detection)
explain <sql>YesRun EXPLAIN and interpret the plan

schema Parameters

ParameterDefaultDescription
--sample-rows, -n3Number of sample rows per table (0 to skip sampling)
--compactfalseCompact text output (suitable for embedding in prompts)

explain Parameters

ParameterDefaultDescription
--analyzefalseUse EXPLAIN ANALYZE (PostgreSQL only; actually executes the query)

Optimization Rules

The optimize command detects the following 13 SQL anti-patterns:

RuleSeverityDescription
avoid-select-starwarningAvoid SELECT *; explicitly list column names
unbounded-queryinfoMissing WHERE and LIMIT clauses
leading-wildcard-likewarningLIKE '%...' causes index to be bypassed
or-conditioninfoOR conditions may prevent index usage
not-in-subquerywarningNOT IN (subquery) has poor performance
scalar-subquerywarningScalar subqueries in SELECT execute row-by-row
function-on-columnwarningFunctions on columns in WHERE prevent index usage
implicit-joininfoImplicit joins (comma-separated tables) are less readable
distinct-usageinfoDISTINCT may mask JOIN duplication issues
order-without-limitinfoORDER BY without LIMIT
deep-nestingwarningDeeply nested subqueries
having-without-groupwarningHAVING without GROUP BY
not-equal-filterinfo!= conditions cannot effectively use indexes

EXPLAIN Interpretation Items

CheckApplicable DatabaseDescription
Full table scanSQLite / PostgreSQLDetects Seq Scan / SCAN TABLE
Auto temporary indexSQLiteSQLite auto-creates a temporary index, indicating a missing permanent index
Covering indexSQLite / PostgreSQLIndex contains all queried columns; no table lookup needed
Disk sortPostgreSQLSort operation spills to disk
Nested loop joinPostgreSQLNested loop joins on large tables have poor performance
Row estimate deviationPostgreSQL (ANALYZE)Estimated rows differ from actual rows by more than 10x

Output Examples

schema --compact

-- Database: sqlite
-- users (1500 rows): id INTEGER  PK, name TEXT, email TEXT, age INTEGER, created_at TEXT
--   IDX(unique): idx_users_email on (email)
-- orders (8200 rows): id INTEGER  PK, user_id INTEGER, amount REAL, status TEXT, created_at TEXT
--   FK: user_id -> users.id
--   IDX: idx_orders_user_id on (user_id)

optimize

{
  "sql": "SELECT * FROM orders o, users u WHERE o.user_id = u.id",
  "issues": [
    {
      "severity": "warning",
      "rule": "avoid-select-star",
      "message": "Avoid SELECT *: only select the columns you need to reduce I/O and network transfer",
      "suggestion": "Replace SELECT * with an explicit list of required column names"
    },
    {
      "severity": "info",
      "rule": "implicit-join",
      "message": "Uses implicit join (comma-separated tables), which is less readable and error-prone",
      "suggestion": "Use explicit JOIN ... ON syntax for better readability and maintainability"
    }
  ]
}

explain (SQLite)

{
  "db_type": "sqlite",
  "query": "SELECT * FROM orders WHERE user_id = 100",
  "plan": [
    {"id": 2, "parent": 0, "detail": "SEARCH orders USING INDEX idx_orders_user_id (user_id=?)"}
  ],
  "interpretation": [
    {
      "severity": "ok",
      "type": "index-search",
      "detail": "Index lookup: idx_orders_user_id",
      "suggestion": "Index lookup is efficient"
    }
  ]
}

Safety Mechanisms

  • Read-only connections: SQLite uses ?mode=ro; PostgreSQL uses SET SESSION READ ONLY
  • SQL whitelist: Only allows statements starting with SELECT / WITH / EXPLAIN
  • Dangerous keyword blocking: INSERT, UPDATE, DELETE, DROP, and 30+ other keywords are blocked
  • Multi-statement blocking: Semicolon-separated multiple SQL statements are rejected
  • Identifier escaping: Table names are double-quote escaped to prevent SQL injection

Dependencies

  • Python 3.8+ (sqlite3 is a built-in module)
  • PostgreSQL support requires: pip install psycopg2-binary
  • The optimize command requires no database connection and has zero external dependencies
Repository
zebbern/claude-code-guide
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.