# QueryTuner β AI-Powered SQL Query Diagnostics
[](CHANGELOG.md)
[](https://api.querytuner.com/docs)
[](https://querytuner.com)
[](https://huggingface.co)
[](LICENSE)
[](https://querytuner.com)
> Only 0.3% of developers are database administrators.
> The SQL performance tools that exist were built for them.
> QueryTuner is for the other 99.7%.
>
> *β Stack Overflow Developer Survey 2024, 65,000+ developers*
**No database connection required. Paste-in and analyze.**
π **Live Demo β [querytuner.com](https://querytuner.com)**
π **API Docs β [/docs](https://api.querytuner.com/docs)**
---
## What It Does
QueryTuner analyzes SQL queries in two layers:
1. **Heuristic Engine** (always on, instant) β rule-based detection of common performance
anti-patterns: missing indexes, leading wildcards, functions in WHERE clauses, SELECT *,
unbounded ORDER BY, and more.
2. **AI Layer** (optional) β powered by HuggingFace (`Qwen/Qwen2.5-Coder`) or OpenAI
(`gpt-4o-mini`). Generates CTE rewrites, CREATE INDEX statements with justification,
and plain-English diagnosis.
---
## Features
- ποΈ **5 Database Dialects** β PostgreSQL, MySQL, Oracle, SQL Server, SQLite
- β‘ **Heuristic Engine** β 12 deterministic rules, always available, no external API calls required
- ποΈ **Schema-Aware Analysis** β paste `CREATE TABLE` DDL and index recommendations upgrade from
estimated to **confirmed**, resolved against your real table and column names
- π§ **Dialect-Correct Index DDL** β `CREATE INDEX CONCURRENTLY` (PostgreSQL),
`ALTER TABLE ... ADD INDEX` (MySQL), `NOLOGGING` (Oracle), `WITH (ONLINE=ON)` (SQL Server)
- π€ **Dual AI Provider** β HuggingFace (default, free) or OpenAI, with structured JSON output
(falls back to readable plain text if the model doesn't return JSON)
- π **Severity-Ranked Findings** β Critical β High β Medium β Low
- π **Optimized Query Output** β rewritten SQL you can copy and run
- π **Shareable Reports** β every analysis gets a permanent `/report/:id` URL
- π **Analytics** β Google Analytics 4 event tracking on every user action
- π‘οΈ **Security Scanning** β detects SQL injection patterns and unsafe constructs
- π **Readability Score** β quantifies query clarity for code review
- π **Client-side query sanitizer** β replace proprietary table and column names with
dummy values before analysis runs. Your real schema names never leave your browser.
One click restores original names in DDL output after analysis. Substitution map
lives in browser memory only β gone on page refresh, never persisted.
- π **REST API** β integrable into CI/CD pipelines and developer tooling
- π« **No DB Connection Needed** β works entirely from pasted query text (schema DDL is optional,
only needed to unlock confirmed mode)
---
## Live API
```bash
# Analyze a query (heuristics only, no API key needed)
curl -X POST https://api.querytuner.com/analyze \
-H "Content-Type: application/json" \
-d '{
"query": "SELECT * FROM orders WHERE customer_id = 42 ORDER BY created_at DESC",
"db_type": "postgresql",
"use_llm": false
}'
# With AI insights (requires HF_API_KEY on server)
curl -X POST https://api.querytuner.com/analyze \
-H "Content-Type: application/json" \
-d '{
"query": "SELECT u.id, COUNT(o.id) FROM users u LEFT JOIN orders o ON o.user_id = u.id WHERE YEAR(o.created_at) = 2025 GROUP BY u.id",
"db_type": "mysql",
"use_llm": true,
"llm_provider": "huggingface"
}'
```
**Supported `db_type` values:** `postgresql` Β· `mysql` Β· `oracle` Β· `sqlserver` Β· `sqlite`
**Supported `llm_provider` values:** `huggingface` Β· `openai`
### Example Response
```json
{
"optimization_suggestions": [
{
"type": "function_in_where",
"severity": "high",
"suggestion": "Avoid wrapping filtered columns in functions inside WHERE",
"reason": "YEAR(created_at) prevents index usage on the created_at column",
"estimated_improvement": "High β use range condition instead"
}
],
"ai_insights": "...",
"optimized_query": "...",
"readability_score": 83.5,
"analysis_time_ms": 5.4,
"used_ai": true,
"ai_model": "Qwen/Qwen2.5-Coder-3B-Instruct"
}
```
Full schema at [`/docs`](https://api.querytuner.com/docs).
---
## Architecture
```
querytuner.com (Vercel) api.querytuner.com (Render)
β β
β POST /analyze β
βββββββββββββββββββββββββββββββββββββββββββΊβ
β
βββββββββββββΌβββββββββββββββ
β FastAPI + SQLAnalyzer β
β ββββββββββββββββββββββ β
β β Heuristic Engine β β β always runs
β β (query_parser.py) β β
β ββββββββββ¬ββββββββββββ β
β β β
β ββββββββββΌββββββββββββ β
β β LLM Router β β β optional
β β HuggingFaceβOpenAIβ β
β ββββββββββββββββββββββ β
ββββββββββββββββββββββββββββ
```
**Stack:**
- Backend: Python Β· FastAPI Β· Pydantic Β· sqlparse Β· LangChain
- Frontend: React Β· Tailwind CSS Β· Axios Β· Lucide Icons
- AI: HuggingFace Inference API (`Qwen/Qwen2.5-Coder-3B-Instruct`) Β· OpenAI-compatible
- Deploy: Render (backend) Β· Vercel (frontend)
---
## Run Locally
**Prerequisites:** Python 3.11+, Node.js 18+
```bash
# Clone
git clone https://github.com/AutoShiftOps/querytuner
cd querytuner
# Backend
cd backend
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # add your HF_API_KEY
uvicorn app.main:app --reload --port 8000
# Frontend (new terminal)
cd frontend
npm install
echo "VITE_API_URL=http://localhost:8000" > .env.local
npm run dev
```
Open `http://localhost:3000` (this project pins Vite's dev server port in `vite.config.js`;
it does not use Vite's default 5173)
---
## Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
| `HF_API_KEY` | Yes (for AI) | β | HuggingFace API key |
| `HF_MODEL` | No | `Qwen/Qwen2.5-Coder-3B-Instruct` | HuggingFace model ID |
| `OPENAI_API_KEY` | No | β | Enables OpenAI provider |
| `OPENAI_MODEL` | No | `gpt-4o-mini` | OpenAI model to use |
| `DEFAULT_LLM_PROVIDER` | No | `huggingface` | Default AI provider |
| `AI_MAX_TOKENS` | No | `800` | Max tokens per LLM response |
| `MAX_QUERY_CHARS` | No | `20000` | Max query input size |
| `SUPABASE_URL` | No | β | Supabase project URL β enables shareable report URLs |
| `SUPABASE_ANON_KEY` | No | β | Supabase anon key β enables analysis persistence |
Create a `.env` file in `/backend` using `.env.example` as the template.
---
## Project Structure
```
sql-query-analyzer/
βββ backend/
β βββ app/
β β βββ agents/
β β β βββ sql_analyzer.py # Main analyzer agent (heuristics + LLM orchestration)
β β β βββ optimizer.py # Query rewrite engine
β β β βββ explainer.py # Plain-English explanation layer
β β βββ llm/
β β β βββ hf_client.py # HuggingFace async client
β β β βββ router.py # Dual-provider LLM router (HF + OpenAI)
β β βββ schemas/
β β β βββ models.py # Pydantic request/response models
β β βββ tools/
β β β βββ query_parser.py # SQL structure extractor + heuristic rules
β β β βββ execution_planner.py
β β β βββ index_recommender.py
β β βββ utils/
β β β βββ config.py
β β β βββ database.py # Supabase persistence β save/fetch analyses
β β β βββ dialect_config.py # Dialect-specific DDL, rewrites, LLM prompts (Phase 1.7)
β β β βββ db_connectors.py
β β βββ main.py # FastAPI app, routes, rate limiting
β βββ migrations/ # Versioned Supabase schema (001_initial_schema.sql, ...)
β βββ LIMITATIONS.md # Known gaps and scope boundaries
β βββ requirements.txt
β βββ Dockerfile
βββ frontend/
β βββ src/
β β βββ components/
β β β βββ QueryInput.jsx
β β β βββ OptimizationSuggestions.jsx
β β β βββ ExecutionPlan.jsx
β β β βββ ResultsPanel.jsx
β β β βββ SampleQueries.jsx # Pre-built example queries
β β β βββ Header.jsx # Sticky enterprise nav
β β β βββ Hero.jsx # Value proposition strip
β β β βββ Footer.jsx # Links + attribution
β β β βββ Toast.jsx # Notification system
β β β βββ ShareButton.jsx # Share analysis URL
β β β βββ QueryDiagnosis.jsx # Structured plain-explanation renderer
β β β βββ ReportPage.jsx # Shareable /report/:id read-only page
β β β βββ SanitizerPanel.jsx # Three-state sanitizer UI
β β βββ utils/
β β β βββ analytics.js # GA4 event tracking
β β β βββ aiInsights.js # Shared AI-JSON parsing (App.jsx + ResultsPanel.jsx)
β β β βββ sanitizer.js # Client-side query sanitizer (substitution map,
β β β # sanitize/desanitize/buildDiff)
β β βββ App.jsx
β βββ package.json
βββ docs/
βββ CHANGELOG.md
βββ .github/workflows/
```
---
## Roadmap
* [x] Core heuristic engine β 12 rules across 5 dialects β Phase 1 β
* [x] Persistent query history (Supabase) β Phase 1.5 β
* [x] Shareable /report/:id URLs β Phase 1.5 β
* [x] Enterprise UI shell (Header, Hero, Footer, Toast) β Phase 1.6 β
* [x] Google Analytics 4 event tracking β Phase 1.6 β
* [x] Dialect-aware DDL, rewrites, and LLM prompts (5 DB types) β Phase 1.7 β
* [x] Schema-aware analysis β paste DDL for confirmed (not just estimated) index suggestions β Phase 2 β
* [ ] LangGraph agentic pipeline β Phase 3 β (deferred post-revenue)
* [ ] API key auth + usage metering β Phase 4 π
* [ ] Stripe payments β Free / Pro / Team tiers β Phase 4 π
* [ ] GitHub Action: `querytuner-analyze` for CI/CD pipelines β Phase 5 π
* [ ] Cross-database execution plan risk normalizer (UEPN) β Phase 5 π
* [ ] Live DB connection mode β Phase 5 π
---
## Known Limitations
See [LIMITATIONS.md](backend/LIMITATIONS.md) for the full list. Key limitations: no live DB
connection, stateless analysis (no query history across runs), LLM availability depends on the
HuggingFace free tier, and LATERAL join correlated-column detection is not yet supported.
---
## Contributing
Issues and PRs welcome. Please open an issue before submitting a large change.
```bash
git checkout -b feature/your-feature
# make changes, add tests
git commit -m "feat: describe your change"
git push origin feature/your-feature
# open a pull request
```
---
## License
MIT Β© 2026 [AutoShiftOps](https://github.com/AutoShiftOps)
Built by [Sudhakar Sajja](https://github.com/AutoShiftOps) β Application Architect, TechMahindra