Analyze SQL. Inspect the real query plan. Recommend an index. Measure the improvement.
A production-style SQL performance analysis and optimization tool built with Python, SQLite, and Streamlit.
The application analyzes SQL queries, detects common performance anti-patterns, runs the real SQLite EXPLAIN QUERY PLAN, generates concrete index recommendations, and validates those recommendations with measured before/after benchmarks.
SQL performance problems can be difficult to diagnose. Developers often need to understand query plans, table scans, indexing strategies, and database behavior before they can determine why a query is slow.
This project provides a complete optimization workflow in one tool:
SQL Query
↓
Static Analysis
↓
Anti-Pattern Detection
↓
Real EXPLAIN QUERY PLAN
↓
Index Recommendation
↓
Before/After Benchmark
↓
Performance Report
The tool is available through both:
- Command-line interface (CLI)
- Streamlit web dashboard
Detects common SQL performance issues including:
SELECT *- Leading-wildcard searches such as
LIKE '%keyword' - Functions applied to columns
- Missing
WHEREclauses - Comma-style / implicit joins
Each detected issue includes an actionable recommendation.
The application executes the actual SQLite:
EXPLAIN QUERY PLANagainst the sample database.
It does not simulate or guess the execution plan.
The analyzer can identify:
- Full table scans
- Index searches
- Table searches
- Query-plan operations
Not every full-table scan is a performance problem.
A small lookup table may be scanned efficiently, while scanning a large table can become expensive.
The tool therefore uses a configurable table-size threshold before reporting a full scan as an optimization issue.
The optimizer extracts relevant columns from the query and generates a ready-to-use SQL statement.
Example:
CREATE INDEX idx_tracks_genre_id
ON tracks (genre_id);This makes the recommendation directly actionable instead of simply telling the developer to "consider an index."
The suggested index can be validated with an actual benchmark.
The process is:
Query without index
↓
Baseline timing
↓
Temporary database copy
↓
Apply suggested index
↓
Optimized timing
↓
Calculate speedup
The original database is never permanently modified during benchmarking.
The web interface provides:
- Query analysis
- Sample query library
- KPI cards
- Interactive results
- Execution-plan information
- Index recommendations
- Benchmark results
- Search/filter controls
- Loading states
- Empty states
- Success/error messages
- CSV/TXT report downloads
| Technology | Purpose |
|---|---|
| Python 3.12 | Core application |
| SQLite | Database engine |
sqlparse |
SQL statement parsing |
pandas |
Data handling and dashboard tables |
| Streamlit | Web dashboard |
| pytest | Automated testing |
| CSV | Report/export support |
SQL Query
│
┌──────────────┴──────────────┐
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ query_analyzer │ │ plan_inspector │
│ │ │ │
│ Static SQL │ │ Real SQLite │
│ anti-patterns │ │ EXPLAIN PLAN │
└────────┬────────┘ └────────┬────────┘
│ │
└──────────────┬─────────────┘
▼
┌──────────────────┐
│ index_advisor │
│ │
│ WHERE-column │
│ extraction │
└────────┬─────────┘
│
▼
Index Suggestion
│
▼
┌──────────────────┐
│ benchmark │
│ │
│ Before / After │
│ timing │
└────────┬─────────┘
│
▼
┌─────────────────────┐
│ optimizer_service │
│ │
│ Pipeline │
│ Orchestration │
└──────────┬──────────┘
│
┌────────┴────────┐
▼ ▼
┌─────────┐ ┌─────────┐
│ main.py │ │ app.py │
│ CLI │ │Streamlit│
└─────────┘ └─────────┘
| Module | Responsibility |
|---|---|
query_analyzer.py |
Static SQL anti-pattern detection |
plan_inspector.py |
Real SQLite query-plan analysis |
index_advisor.py |
Index recommendation generation |
benchmark.py |
Before/after performance measurement |
optimizer_service.py |
Orchestrates the complete optimization pipeline |
sample_database.py |
Creates the local sample database |
exceptions.py |
Custom application exceptions |
config.py |
Application configuration and thresholds |
sql-query-optimizer/
│
├── src/
│ ├── config.py
│ ├── exceptions.py
│ ├── sample_database.py
│ ├── query_analyzer.py
│ ├── plan_inspector.py
│ ├── index_advisor.py
│ ├── benchmark.py
│ └── optimizer_service.py
│
├── tests/
│ ├── test_sample_database.py
│ ├── test_query_analyzer.py
│ ├── test_plan_inspector.py
│ ├── test_index_advisor.py
│ ├── test_benchmark.py
│ └── test_optimizer_service.py
│
├── data/
│ └── sample_store.db
│
├── main.py
├── app.py
├── requirements.txt
├── GUIDE.txt
├── README.md
└── LICENSE
Make sure the following are installed:
- Python 3.11+
- Git
- pip
- VS Code or another code editor
Check Python:
python --versionCheck Git:
git --versiongit clone <YOUR-REPOSITORY-URL>Move into the project directory:
cd sql-query-optimizerpython -m venv venvActivate it:
venv\Scripts\activatepython3 -m venv venvActivate it:
source venv/bin/activatepip install -r requirements.txtFollow these steps in order.
Run:
python main.py --build-dbThis creates the local SQLite database used by the optimizer.
The database is generated under:
data/sample_store.db
To rebuild the database from scratch:
python main.py --build-db --force-rebuildRun:
python main.py --analyze "SELECT * FROM tracks WHERE genre_id = 3"The tool will analyze the query for:
- SQL anti-patterns
- Full-table scans
- Query-plan behavior
- Index opportunities
Create a file such as:
my_query.sql
Add:
SELECT *
FROM tracks
WHERE genre_id = 3;Then run:
python main.py --analyze-file my_query.sqlRun:
python main.py --benchmark "SELECT * FROM tracks WHERE genre_id = 3"The benchmark compares query performance before and after applying the suggested index.
Example:
Before: 0.0042 seconds
After: 0.0029 seconds
Speedup: 1.45x
Actual values depend on the machine and execution environment.
After building the database, launch:
streamlit run app.pyStreamlit will display a local URL similar to:
Local URL: http://localhost:8501
Open that address in your browser.
Open:
Analyze a Query
from the sidebar.
Choose one of the included sample queries.
You can also enter custom SQL.
Example:
SELECT *
FROM tracks
WHERE genre_id = 3;Click:
Run Analysis
The dashboard displays:
Anti-Patterns
↓
Execution Plan
↓
Index Recommendations
Click:
Benchmark Top Suggestion
to measure the real before/after performance.
Analysis results can be exported as:
- CSV
- TXT
The project uses a Chinook-style relational database schema containing:
- Artists
- Albums
- Tracks
- Genres
- Customers
- Invoices
- Invoice Items
The schema is designed to provide realistic relationships between tables for SQL query-plan and indexing analysis.
The local database generator recreates this schema and generates reproducible data using a fixed seed.
The generated dataset contains approximately:
2,500 tracks
4,500 invoice items
350 customers
15 genres
The original Chinook database could not be downloaded in the restricted development environment, so the project includes a local schema-compatible generator.
The application can also work with a compatible SQLite database when configured appropriately.
Run the complete test suite:
python -m pytest tests/ -vCurrent test suite:
49 tests
49 passing
The tests cover:
- Anti-pattern detection
- Positive and negative cases
- Database generation
- Foreign-key integrity
- Query-plan inspection
- Full-scan detection
- Small-table false-positive prevention
- Index recommendations
- Multi-table query handling
- Benchmark isolation
- Service orchestration
During testing, a real bug was discovered in multi-table index recommendation.
For example:
SELECT *
FROM tracks, albums
WHERE albums.title = 'X';The incorrect implementation could associate:
albums.title
with the wrong table.
This could result in an invalid recommendation such as:
CREATE INDEX idx_tracks_title
ON tracks (title);even though tracks does not contain a title column.
The index-advisor logic was updated to correctly handle table-qualified columns:
table.column
For multi-table queries, qualified columns are attributed only to their referenced table.
Regression tests were added to ensure this behavior remains correct.
The project intentionally separates:
What does the SQL look like?
from:
What is the database actually doing?
Static analysis identifies suspicious query patterns, while EXPLAIN QUERY PLAN reveals the database's actual execution strategy.
A full scan of a tiny table may be perfectly reasonable.
Therefore, the tool uses a configurable threshold to avoid producing unnecessary warnings.
Benchmarking is performed on a temporary database copy.
Original Database
↓
Temporary Copy
↓
Apply Index
↓
Run Benchmark
↓
Compare Results
↓
Temporary Copy Removed
This allows benchmarks to be safely repeated.
optimizer_service.py orchestrates the complete optimization workflow.
Both:
main.py
app.py
use the same service layer instead of duplicating business logic.
The current version supports SELECT statements.
Unsupported examples:
INSERT ...
UPDATE ...
DELETE ...Use a SELECT query instead.
This usually means the query references a table or column that does not exist in the sample database.
Check the available tables:
artists
albums
tracks
genres
customers
invoices
invoice_items
Build the database first:
python main.py --build-dbThen launch:
streamlit run app.pyMake sure your virtual environment is activated.
Windows:
venv\Scripts\activateThen reinstall:
pip install -r requirements.txtRun Streamlit on another port:
streamlit run app.py --server.port 8502Then open:
http://localhost:8502
Streamlit Community Cloud is the recommended deployment option for this project.
- Push the repository to GitHub.
- Open Streamlit Community Cloud.
- Connect your GitHub account.
- Select the repository.
- Select branch:
main
- Set the main application file:
app.py
- Deploy.
The dependencies will be installed from:
requirements.txt
Because the application requires the sample SQLite database, the deployment configuration should ensure that the database is available/generated before analysis begins.
The project can also be deployed as a Streamlit web service.
pip install -r requirements.txtstreamlit run app.py --server.port $PORT --server.address 0.0.0.0Use an LLM to generate optimized SQL rewrites for complex queries.
Allow users to upload their own SQLite databases for analysis.
Add support for:
- PostgreSQL
- MySQL
with database-specific execution-plan analysis.
Support datasets containing:
100,000+ rows
to demonstrate indexing impact at larger scales.
Store historical query analyses and performance results.
Generate multi-column indexes when queries filter on multiple columns.
BS Artificial Intelligence Student University of Sindh, Jamshoro
I am an AI-focused developer interested in building practical, production-oriented software systems and intelligent developer tools.
- Artificial Intelligence
- Machine Learning
- Natural Language Processing
- AI Research
- Software Engineering
- Intelligent Developer Tools
Python
Machine Learning
Artificial Intelligence
NLP
SQL & Databases
Software Engineering
Contributions are welcome.
git clone <YOUR-REPOSITORY-URL>git checkout -b feature/your-feature- PEP 8
- Type hints
- Clear naming
- Google-style docstrings
- Logging
- Error handling
- Automated tests
python -m pytest tests/ -vInclude a clear description of:
- What changed
- Why it changed
- How it was tested
This project is licensed under the MIT License.
See the LICENSE file for details.
If you find this project useful:
- ⭐ Star the repository
- 🐛 Report issues
- 💡 Suggest improvements
- 🤝 Contribute to the project
SQL Query Optimizer Tool demonstrates a practical database-performance workflow:
Detect
↓
Inspect
↓
Recommend
↓
Benchmark
↓
Measure
Don't guess that an optimization works. Measure it.