SQLRay is a tool that helps you optimize SQL queries using OpenAI.
Project description
SQL Query Optimizer CLI
This CLI tool leverages the capabilities of SQLRay and OpenAI to analyze and optimize SQL queries. It's designed to improve the performance of your SQL queries by suggesting optimizations based on your database schema and the specifics of your query.
Features
- Optimize SQL Queries: Submit your SQL query to be optimized based on your actual database schema.
- Interactive Mode: Enter interactive mode to continuously optimize SQL queries with the ability to load a new schema as needed.
- OpenAI Integration: Utilizes OpenAI's powerful models to suggest optimizations.
Getting Started with SQLRay (Docker)
- First of all, get the database schema and save a file database_schema.json with the schema. You can generate the schema directly from
Get database schemasection below. - Run the following command to start the SQLRay container:
docker run -it --rm -v $(pwd)/:/tmp/local -w /tmp/local ghcr.io/josecarlosgarcia95/sqlray:main interactive
- Once the container is running, you can start optimizing your SQL queries.
Example
I have the schema in a file called database_schema.json on my current working directory.
❯ docker run -it --rm -v $(pwd)/:/tmp/local -w /tmp/local ghcr.io/josecarlosgarcia95/sqlray:main interactive
Welcome to the interactive mode.
Please enter the OpenAI model [gpt-4o]:
Please enter the OpenAI API key: sk-xxxx
Please enter the path to your database schema JSON file: database_schema.json
Database schema loaded successfully.
If you enter a file path, the query will be read from the file.
Please enter your SQL query (Type 'exit' to quit): SELECT * FROM users WHERE id = 1;
Get database schema
To get the database schema, you can use the following command:
MySQL 8.0+
SELECT JSON_OBJECT('columns',(SELECT JSON_ARRAYAGG(JSON_OBJECT('schema',cols.table_schema,'table',cols.table_name,'name',cols.column_name,'type',cols.column_type,'nullable',(cols.IS_NULLABLE='YES'),'collation',cols.COLLATION_NAME)) FROM information_schema.columns AS cols),'indexes',(SELECT JSON_ARRAYAGG(JSON_OBJECT('schema',idx.table_schema,'table',idx.table_name,'name',idx.index_name,'size',(SELECT IFNULL(SUM(stat_value*@@innodb_page_size),-1) FROM mysql.innodb_index_stats WHERE stat_name='size' AND index_name=idx.index_name AND table_name=idx.table_name AND database_name=idx.table_schema),'column',idx.column_name,'index_type',LOWER(idx.index_type),'cardinality',idx.cardinality,'direction',CASE WHEN idx.collation='D' THEN 'desc' ELSE 'asc' END,'unique',(idx.non_unique=0))) FROM information_schema.statistics AS idx),'tables',(SELECT JSON_ARRAYAGG(JSON_OBJECT('schema',tbls.TABLE_SCHEMA,'table',tbls.TABLE_NAME,'rows',IFNULL(tbls.TABLE_ROWS,0),'type',IFNULL(tbls.TABLE_TYPE,''),'engine',IFNULL(tbls.ENGINE,''),'collation',IFNULL(tbls.TABLE_COLLATION,''))) FROM information_schema.tables AS tbls),'views',(SELECT JSON_ARRAYAGG(JSON_OBJECT('schema',v.TABLE_SCHEMA,'view_name',v.TABLE_NAME,'definition',REPLACE(REPLACE(TO_BASE64(v.VIEW_DEFINITION),' ',''),'\n',''))) FROM information_schema.views AS v),'server_name',@@hostname,'version',VERSION()) AS info;
MySQL 5.7+
SELECT CONCAT( '{', '"columns": [', GROUP_CONCAT(DISTINCT columns_json SEPARATOR ','), '],', '"indexes": [', GROUP_CONCAT(DISTINCT indexes_json SEPARATOR ','), '],', '"tables": [', GROUP_CONCAT(DISTINCT tables_json SEPARATOR ','), '],', '"views": [', GROUP_CONCAT(DISTINCT views_json SEPARATOR ','), '],', '"server_name": "', @@hostname, '",', '"version": "', VERSION(), '"', '}') AS info FROM( SELECT CONCAT( '{', '"schema": "', cols.table_schema, '",', '"table": "', cols.table_name, '",', '"name": "', cols.column_name, '",', '"type": "', cols.column_type, '",', '"nullable": ', IF(cols.IS_NULLABLE = 'YES', 'true', 'false'), ',', '"collation": "', IFNULL(cols.COLLATION_NAME, ''), '"', '}' ) AS columns_json, NULL AS indexes_json, NULL AS tables_json, NULL AS views_json FROM information_schema.columns cols WHERE cols.table_schema = DATABASE() UNION ALL SELECT NULL, CONCAT( '{', '"schema": "', indexes.table_schema, '",', '"table": "', indexes.table_name, '",', '"name": "', indexes.index_name, '",', '"column": "', indexes.column_name, '",', '"index_type": "', LOWER(indexes.index_type), '",', '"cardinality": ', indexes.cardinality, ',', '"direction": "', IF(indexes.collation = 'D', 'desc', 'asc'), '",', '"unique": ', IF(indexes.non_unique = 0, 'true', 'false'), '}' ), NULL, NULL FROM information_schema.statistics indexes WHERE indexes.table_schema = DATABASE() UNION ALL SELECT NULL, NULL, CONCAT( '{', '"schema": "', tbls.TABLE_SCHEMA, '",', '"table": "', tbls.TABLE_NAME, '",', '"rows": ', IFNULL(tbls.TABLE_ROWS, 0), ',', '"type": "', IFNULL(tbls.TABLE_TYPE, ''), '",', '"engine": "', IFNULL(tbls.ENGINE, ''), '",', '"collation": "', IFNULL(tbls.TABLE_COLLATION, ''), '"', '}' ), NULL FROM information_schema.tables tbls WHERE tbls.table_schema = DATABASE() UNION ALL SELECT NULL, NULL, NULL, CONCAT( '{', '"schema": "', views.TABLE_SCHEMA, '",', '"view_name": "', views.TABLE_NAME, '",', '"definition": "', REPLACE(REPLACE(TO_BASE64(views.VIEW_DEFINITION), ' ', ''), '
', ''), '"', '}' ) FROM information_schema.views views WHERE views.table_schema = DATABASE() ) AS subqueries;
PostgreSQL
SELECT json_build_object( 'columns',( SELECT json_agg( json_build_object( 'schema', cols.table_schema, 'table', cols.table_name, 'name', cols.column_name, 'type', cols.data_type, 'nullable', (cols.is_nullable = 'YES'), 'collation', cols.collation_name) ) FROM information_schema.columns cols WHERE cols.table_schema = current_schema() ), 'indexes', ( SELECT json_agg( json_build_object( 'schema', ix.schemaname, 'table', ix.tablename, 'name', ix.indexname, 'definition', ix.indexdef ) ) FROM pg_indexes ix WHERE ix.schemaname = current_schema() ), 'tables', ( SELECT json_agg( json_build_object( 'schema', tbl.table_schema, 'table', tbl.table_name, 'type', tbl.table_type, 'rows', ( SELECT reltuples::bigint FROM pg_class WHERE oid = ('"' || tbl.table_schema || '"."' || tbl.table_name || '"')::regclass ), 'engine', 'N/A', 'collation', 'N/A' ) ) FROM information_schema.tables tbl WHERE tbl.table_schema = current_schema() ), 'views', ( SELECT json_agg( json_build_object( 'schema', v.table_schema, 'view_name', v.table_name, 'definition', pg_get_viewdef(('"' || v.table_schema || '"."' || v.table_name || '"')::regclass) ) ) FROM information_schema.views v WHERE v.table_schema = current_schema() ), 'server_name', '', 'version', version() ) AS info;
This command will return a JSON object with the database schema, please create a file with the output.
Installation
Before you can run the tool, ensure you have Python installed on your system. This tool has been tested with Python 3.8 and above.
You can install directly from PyPI using pip:
sudo pip install sqlray
You can run directly sqlray from the command line:
sqlray --help
Or using python -m:
python -m sqlray --help
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqlray-1.0.1.tar.gz.
File metadata
- Download URL: sqlray-1.0.1.tar.gz
- Upload date:
- Size: 22.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
746b3688ea7ed48fb0e641a0e35aed2461981899ed2696aaff5bb234b5852aeb
|
|
| MD5 |
e8cf9b9d75db0b42fc37ebdb5d013378
|
|
| BLAKE2b-256 |
73b539bf0759978b8ca5f2e9b9969fe4ba4abcd36a4af57b2824b5248b52d3b4
|
File details
Details for the file sqlray-1.0.1-py3-none-any.whl.
File metadata
- Download URL: sqlray-1.0.1-py3-none-any.whl
- Upload date:
- Size: 20.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e7af2e091279b605a66aee2a7baa7f488175bedfa78f977bdf25e7bd5447ba49
|
|
| MD5 |
c4ca091b1b146ca84097049cfa154455
|
|
| BLAKE2b-256 |
91410c8158c6585b41c87a77c50ae46e59f19b80282e6f5e6358ec7ef6a66acd
|