From c0f3df30fe2f19800cd98368f7dca49c18a5d645 Mon Sep 17 00:00:00 2001 From: gargsaumya Date: Wed, 23 Jul 2025 13:31:59 +0530 Subject: [PATCH 1/2] updated script and adding to github for public --- benchmarks/README.md | 40 +++ benchmarks/bench_mssql.py | 686 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 726 insertions(+) create mode 100644 benchmarks/README.md create mode 100644 benchmarks/bench_mssql.py diff --git a/benchmarks/README.md b/benchmarks/README.md new file mode 100644 index 00000000..bde6fb26 --- /dev/null +++ b/benchmarks/README.md @@ -0,0 +1,40 @@ +# Benchmarks + +This directory contains benchmark scripts for testing the performance of various database operations using `pyodbc` and `mssql_python`. The goal is to evaluate and compare the performance of these libraries for common database operations. + +## Why Benchmarks? +- To measure the efficiency of `pyodbc` and `mssql_python` in handling database operations. +- To identify performance bottlenecks and optimize database interactions. +- To ensure the reliability and scalability of the libraries under different workloads. + +## How to Run Benchmarks +1. **Set Up the Environment Variable**: + - Ensure you have a running SQL Server instance. + - Set the `DB_CONNECTION_STRING` environment variable with the connection string to your database. For example: + ```cmd + set DB_CONNECTION_STRING=Server=your_server;Database=your_database;UID=your_user;PWD=your_password; + ``` + +2. **Install Richbench - Benchmarking Tool**: + - Install richbench : + ```cmd + pip install richbench + ``` + +3. **Run the Benchmarks**: + - Execute richbench from the parent folder (mssql-python) : + ```cmd + richbench benchmarks + ``` + Results will be displayed in the terminal with detailed performance metrics. + +## Key Features of `bench_mssql.py` +- **Comprehensive Benchmarks**: Includes SELECT, INSERT, UPDATE, DELETE, complex queries, stored procedures, and transaction handling. +- **Error Handling**: Each benchmark function is wrapped with error handling to ensure smooth execution. +- **Progress Messages**: Clear progress messages are printed during execution for better visibility. +- **Automated Setup and Cleanup**: The script automatically sets up and cleans up the database environment before and after the benchmarks. + +## Notes +- Ensure the database user has the necessary permissions to create and drop tables and stored procedures. +- The script uses permanent tables prefixed with `perfbenchmark_` for benchmarking purposes. +- A stored procedure named `perfbenchmark_stored_procedure` is created and used during the benchmarks. \ No newline at end of file diff --git a/benchmarks/bench_mssql.py b/benchmarks/bench_mssql.py new file mode 100644 index 00000000..d8724f01 --- /dev/null +++ b/benchmarks/bench_mssql.py @@ -0,0 +1,686 @@ +import atexit +import pyodbc +import os +import sys +import threading +import time +import mssql_python + +CONNECTION_STRING = "Driver={ODBC Driver 18 for SQL Server};" + os.environ.get('DB_CONNECTION_STRING') + +def setup_database(): + print("Setting up the database...") + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + try: + # Drop permanent tables and stored procedure if they exist + print("Dropping existing tables and stored procedure if they exist...") + cursor.execute(""" + IF OBJECT_ID('perfbenchmark_child_table', 'U') IS NOT NULL DROP TABLE perfbenchmark_child_table; + IF OBJECT_ID('perfbenchmark_parent_table', 'U') IS NOT NULL DROP TABLE perfbenchmark_parent_table; + IF OBJECT_ID('perfbenchmark_table', 'U') IS NOT NULL DROP TABLE perfbenchmark_table; + IF OBJECT_ID('perfbenchmark_stored_procedure', 'P') IS NOT NULL DROP PROCEDURE perfbenchmark_stored_procedure; + """) + + # Create permanent tables with new names + print("Creating tables...") + cursor.execute(""" + CREATE TABLE perfbenchmark_table ( + id INT, + name NVARCHAR(50), + age INT + ) + """) + + cursor.execute(""" + CREATE TABLE perfbenchmark_parent_table ( + id INT PRIMARY KEY, + name NVARCHAR(50) + ) + """) + + cursor.execute(""" + CREATE TABLE perfbenchmark_child_table ( + id INT PRIMARY KEY, + parent_id INT, + description NVARCHAR(100), + FOREIGN KEY (parent_id) REFERENCES perfbenchmark_parent_table(id) + ) + """) + + # Create stored procedure + print("Creating stored procedure...") + cursor.execute(""" + CREATE PROCEDURE perfbenchmark_stored_procedure + AS + BEGIN + SELECT * FROM perfbenchmark_table; + END + """) + + conn.commit() + print("Database setup completed.") + finally: + cursor.close() + conn.close() + +# Call setup_database to ensure permanent tables and procedure are recreated +setup_database() + +def cleanup_database(): + print("Cleaning up the database...") + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + try: + # Drop tables and stored procedure after benchmarks + print("Dropping tables and stored procedure...") + cursor.execute(""" + IF OBJECT_ID('perfbenchmark_child_table', 'U') IS NOT NULL DROP TABLE perfbenchmark_child_table; + IF OBJECT_ID('perfbenchmark_parent_table', 'U') IS NOT NULL DROP TABLE perfbenchmark_parent_table; + IF OBJECT_ID('perfbenchmark_table', 'U') IS NOT NULL DROP TABLE perfbenchmark_table; + IF OBJECT_ID('perfbenchmark_stored_procedure', 'P') IS NOT NULL DROP PROCEDURE perfbenchmark_stored_procedure; + """) + conn.commit() + print("Database cleanup completed.") + finally: + cursor.close() + conn.close() + +# Register cleanup function to run at exit +atexit.register(cleanup_database) + +# Define benchmark functions for pyodbc +def bench_select_pyodbc(): + print("Running SELECT benchmark with pyodbc...") + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + + # Clear plan and data cache + cursor.execute("CHECKPOINT;") + cursor.execute("DBCC DROPCLEANBUFFERS;") + cursor.execute("DBCC FREEPROCCACHE;") + + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchall() + cursor.close() + conn.close() + print("SELECT benchmark with pyodbc completed.") + +def bench_insert_pyodbc(): + print("Running INSERT benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("INSERT INTO perfbenchmark_table (id, name, age) VALUES (1, 'John Doe', 30)") + conn.commit() + cursor.close() + conn.close() + print("INSERT benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during INSERT benchmark: {e}") + +def bench_update_pyodbc(): + print("Running UPDATE benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("UPDATE perfbenchmark_table SET age = 31 WHERE id = 1") + conn.commit() + cursor.close() + conn.close() + print("UPDATE benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during UPDATE benchmark: {e}") + +def bench_delete_pyodbc(): + print("Running DELETE benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("DELETE FROM perfbenchmark_table WHERE id = 1") + conn.commit() + cursor.close() + conn.close() + print("DELETE benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during DELETE benchmark: {e}") + +def bench_complex_query_pyodbc(): + print("Running COMPLEX QUERY benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""SELECT name, COUNT(*) + FROM perfbenchmark_table + GROUP BY name + HAVING COUNT(*) > 1 + """) + cursor.fetchall() + cursor.close() + conn.close() + print("COMPLEX QUERY benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during COMPLEX QUERY benchmark: {e}") + +def bench_multiple_connections_pyodbc(): + print("Running MULTIPLE CONNECTIONS benchmark with pyodbc...") + try: + connections = [] + for _ in range(10): + conn = pyodbc.connect(CONNECTION_STRING) + connections.append(conn) + + for conn in connections: + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchall() + cursor.close() + + for conn in connections: + conn.close() + print("MULTIPLE CONNECTIONS benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during MULTIPLE CONNECTIONS benchmark: {e}") + +def bench_100_inserts_pyodbc(): + print("Running 100 INSERTS benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + data = [(i, 'John Doe', 30) for i in range(100)] + cursor.executemany("INSERT INTO perfbenchmark_table (id, name, age) VALUES (?, ?, ?)", data) + conn.commit() + cursor.close() + conn.close() + print("100 INSERTS benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during 100 INSERTS benchmark: {e}") + +def bench_fetchone_pyodbc(): + print("Running FETCHONE benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchone() + cursor.close() + conn.close() + print("FETCHONE benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during FETCHONE benchmark: {e}") + +def bench_fetchmany_pyodbc(): + print("Running FETCHMANY benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchmany(10) + cursor.close() + conn.close() + print("FETCHMANY benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during FETCHMANY benchmark: {e}") + +def bench_executemany_pyodbc(): + print("Running EXECUTEMANY benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.fast_executemany = True + data = [(i, 'John Doe', 30) for i in range(100)] + cursor.executemany("INSERT INTO perfbenchmark_table (id, name, age) VALUES (?, ?, ?)", data) + conn.commit() + cursor.close() + conn.close() + print("EXECUTEMANY benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during EXECUTEMANY benchmark: {e}") + +def bench_stored_procedure_pyodbc(): + print("Running STORED PROCEDURE benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("{CALL perfbenchmark_stored_procedure}") + cursor.fetchall() + cursor.close() + conn.close() + print("STORED PROCEDURE benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during STORED PROCEDURE benchmark: {e}") + +def bench_nested_query_pyodbc(): + print("Running NESTED QUERY benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""SELECT * FROM ( + SELECT name, age FROM perfbenchmark_table + ) AS subquery + WHERE age > 25 + """) + cursor.fetchall() + cursor.close() + conn.close() + print("NESTED QUERY benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during NESTED QUERY benchmark: {e}") + +def bench_join_query_pyodbc(): + print("Running JOIN QUERY benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""SELECT a.name, b.age + FROM perfbenchmark_table a + JOIN perfbenchmark_table b ON a.id = b.id + """) + cursor.fetchall() + cursor.close() + conn.close() + print("JOIN QUERY benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during JOIN QUERY benchmark: {e}") + +def bench_transaction_pyodbc(): + print("Running TRANSACTION benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + try: + cursor.execute("BEGIN TRANSACTION") + cursor.execute("INSERT INTO perfbenchmark_table (id, name, age) VALUES (1, 'John Doe', 30)") + cursor.execute("UPDATE perfbenchmark_table SET age = 31 WHERE id = 1") + cursor.execute("DELETE FROM perfbenchmark_table WHERE id = 1") + cursor.execute("COMMIT") + except: + cursor.execute("ROLLBACK") + cursor.close() + conn.close() + print("TRANSACTION benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during TRANSACTION benchmark: {e}") + +def bench_large_data_set_pyodbc(): + print("Running LARGE DATA SET benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + while cursor.fetchone(): + pass + cursor.close() + conn.close() + print("LARGE DATA SET benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during LARGE DATA SET benchmark: {e}") + +def bench_update_with_join_pyodbc(): + print("Running UPDATE WITH JOIN benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""UPDATE perfbenchmark_child_table + SET description = 'Updated Child 1' + FROM perfbenchmark_child_table c + JOIN perfbenchmark_parent_table p ON c.parent_id = p.id + WHERE p.name = 'Parent 1' + """) + conn.commit() + cursor.close() + conn.close() + print("UPDATE WITH JOIN benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during UPDATE WITH JOIN benchmark: {e}") + +def bench_delete_with_join_pyodbc(): + print("Running DELETE WITH JOIN benchmark with pyodbc...") + try: + conn = pyodbc.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""DELETE c + FROM perfbenchmark_child_table c + JOIN perfbenchmark_parent_table p ON c.parent_id = p.id + WHERE p.name = 'Parent 1' + """) + conn.commit() + cursor.close() + conn.close() + print("DELETE WITH JOIN benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during DELETE WITH JOIN benchmark: {e}") + +def bench_multiple_connections_pyodbc(): + print("Running MULTIPLE CONNECTIONS benchmark with pyodbc...") + try: + connections = [] + for _ in range(10): + conn = pyodbc.connect(CONNECTION_STRING) + connections.append(conn) + + for conn in connections: + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchall() + cursor.close() + + for conn in connections: + conn.close() + print("MULTIPLE CONNECTIONS benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during MULTIPLE CONNECTIONS benchmark: {e}") + +def bench_1000_connections_pyodbc(): + print("Running 1000 CONNECTIONS benchmark with pyodbc...") + try: + threads = [] + for _ in range(1000): + thread = threading.Thread(target=lambda: pyodbc.connect(CONNECTION_STRING).close()) + threads.append(thread) + thread.start() + for thread in threads: + thread.join() + print("1000 CONNECTIONS benchmark with pyodbc completed.") + except Exception as e: + print(f"Error during 1000 CONNECTIONS benchmark: {e}") + +# Define benchmark functions for mssql_python +def bench_select_mssql_python(): + print("Running SELECT benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + + # Clear plan and data cache + cursor.execute("CHECKPOINT;") + cursor.execute("DBCC DROPCLEANBUFFERS;") + cursor.execute("DBCC FREEPROCCACHE;") + + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchall() + cursor.close() + conn.close() + print("SELECT benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during SELECT benchmark with mssql_python: {e}") + +def bench_insert_mssql_python(): + print("Running INSERT benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("INSERT INTO perfbenchmark_table (id, name, age) VALUES (1, 'John Doe', 30)") + conn.commit() + cursor.close() + conn.close() + print("INSERT benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during INSERT benchmark with mssql_python: {e}") + +def bench_update_mssql_python(): + print("Running UPDATE benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("UPDATE perfbenchmark_table SET age = 31 WHERE id = 1") + conn.commit() + cursor.close() + conn.close() + print("UPDATE benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during UPDATE benchmark with mssql_python: {e}") + +def bench_delete_mssql_python(): + print("Running DELETE benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("DELETE FROM perfbenchmark_table WHERE id = 1") + conn.commit() + cursor.close() + conn.close() + print("DELETE benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during DELETE benchmark with mssql_python: {e}") + +def bench_complex_query_mssql_python(): + print("Running COMPLEX QUERY benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""SELECT name, COUNT(*) + FROM perfbenchmark_table + GROUP BY name + HAVING COUNT(*) > 1 + """) + cursor.fetchall() + cursor.close() + conn.close() + print("COMPLEX QUERY benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during COMPLEX QUERY benchmark with mssql_python: {e}") + +def bench_100_inserts_mssql_python(): + print("Running 100 INSERTS benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + data = [(i, 'John Doe', 30) for i in range(100)] + cursor.executemany("INSERT INTO perfbenchmark_table (id, name, age) VALUES (?, 'John Doe', 30)", data) + conn.commit() + cursor.close() + conn.close() + print("100 INSERTS benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during 100 INSERTS benchmark with mssql_python: {e}") + +def bench_fetchone_mssql_python(): + print("Running FETCHONE benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchone() + cursor.close() + conn.close() + print("FETCHONE benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during FETCHONE benchmark with mssql_python: {e}") + +def bench_fetchmany_mssql_python(): + print("Running FETCHMANY benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchmany(10) + cursor.close() + conn.close() + print("FETCHMANY benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during FETCHMANY benchmark with mssql_python: {e}") + +def bench_executemany_mssql_python(): + print("Running EXECUTEMANY benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + data = [(i, 'John Doe', 30) for i in range(100)] + cursor.executemany("INSERT INTO perfbenchmark_table (id, name, age) VALUES (?, ?, ?)", data) + conn.commit() + cursor.close() + conn.close() + print("EXECUTEMANY benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during EXECUTEMANY benchmark with mssql_python: {e}") + +def bench_stored_procedure_mssql_python(): + print("Running STORED PROCEDURE benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("{CALL perfbenchmark_stored_procedure}") + cursor.fetchall() + cursor.close() + conn.close() + print("STORED PROCEDURE benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during STORED PROCEDURE benchmark with mssql_python: {e}") + +def bench_nested_query_mssql_python(): + print("Running NESTED QUERY benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""SELECT * FROM ( + SELECT name, age FROM perfbenchmark_table + ) AS subquery + WHERE age > 25 + """) + cursor.fetchall() + cursor.close() + conn.close() + print("NESTED QUERY benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during NESTED QUERY benchmark with mssql_python: {e}") + +def bench_join_query_mssql_python(): + print("Running JOIN QUERY benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""SELECT a.name, b.age + FROM perfbenchmark_table a + JOIN perfbenchmark_table b ON a.id = b.id + """) + cursor.fetchall() + cursor.close() + conn.close() + print("JOIN QUERY benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during JOIN QUERY benchmark with mssql_python: {e}") + +def bench_transaction_mssql_python(): + print("Running TRANSACTION benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + try: + cursor.execute("BEGIN TRANSACTION") + cursor.execute("INSERT INTO perfbenchmark_table (id, name, age) VALUES (1, 'John Doe', 30)") + cursor.execute("UPDATE perfbenchmark_table SET age = 31 WHERE id = 1") + cursor.execute("DELETE FROM perfbenchmark_table WHERE id = 1") + cursor.execute("COMMIT") + except: + cursor.execute("ROLLBACK") + cursor.close() + conn.close() + print("TRANSACTION benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during TRANSACTION benchmark with mssql_python: {e}") + +def bench_large_data_set_mssql_python(): + print("Running LARGE DATA SET benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + while cursor.fetchone(): + pass + cursor.close() + conn.close() + print("LARGE DATA SET benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during LARGE DATA SET benchmark with mssql_python: {e}") + +def bench_update_with_join_mssql_python(): + print("Running UPDATE WITH JOIN benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""UPDATE perfbenchmark_child_table + SET description = 'Updated Child 1' + FROM perfbenchmark_child_table c + JOIN perfbenchmark_parent_table p ON c.parent_id = p.id + WHERE p.name = 'Parent 1' + """) + conn.commit() + cursor.close() + conn.close() + print("UPDATE WITH JOIN benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during UPDATE WITH JOIN benchmark with mssql_python: {e}") + +def bench_delete_with_join_mssql_python(): + print("Running DELETE WITH JOIN benchmark with mssql_python...") + try: + conn = mssql_python.connect(CONNECTION_STRING) + cursor = conn.cursor() + cursor.execute("""DELETE c + FROM perfbenchmark_child_table c + JOIN perfbenchmark_parent_table p ON c.parent_id = p.id + WHERE p.name = 'Parent 1' + """) + conn.commit() + cursor.close() + conn.close() + print("DELETE WITH JOIN benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during DELETE WITH JOIN benchmark with mssql_python: {e}") + +def bench_multiple_connections_mssql_python(): + print("Running MULTIPLE CONNECTIONS benchmark with mssql_python...") + try: + connections = [] + for _ in range(10): + conn = mssql_python.connect(CONNECTION_STRING) + connections.append(conn) + + for conn in connections: + cursor = conn.cursor() + cursor.execute("SELECT * FROM perfbenchmark_table") + cursor.fetchall() + cursor.close() + + for conn in connections: + conn.close() + print("MULTIPLE CONNECTIONS benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during MULTIPLE CONNECTIONS benchmark with mssql_python: {e}") + +def bench_1000_connections_mssql_python(): + print("Running 1000 CONNECTIONS benchmark with mssql_python...") + try: + threads = [] + for _ in range(1000): + thread = threading.Thread(target=lambda: mssql_python.connect(CONNECTION_STRING).close()) + threads.append(thread) + thread.start() + for thread in threads: + thread.join() + print("1000 CONNECTIONS benchmark with mssql_python completed.") + except Exception as e: + print(f"Error during 1000 CONNECTIONS benchmark with mssql_python: {e}") + +# Define benchmarks +__benchmarks__ = [ + (bench_select_pyodbc, bench_select_mssql_python, "SELECT operation"), + (bench_insert_pyodbc, bench_insert_mssql_python, "INSERT operation"), + (bench_update_pyodbc, bench_update_mssql_python, "UPDATE operation"), + (bench_delete_pyodbc, bench_delete_mssql_python, "DELETE operation"), + (bench_complex_query_pyodbc, bench_complex_query_mssql_python, "Complex query operation"), + (bench_multiple_connections_pyodbc, bench_multiple_connections_mssql_python, "Multiple connections operation"), + (bench_fetchone_pyodbc, bench_fetchone_mssql_python, "Fetch one operation"), + (bench_fetchmany_pyodbc, bench_fetchmany_mssql_python, "Fetch many operation"), + (bench_stored_procedure_pyodbc, bench_stored_procedure_mssql_python, "Stored procedure operation"), + (bench_1000_connections_pyodbc, bench_1000_connections_mssql_python, "1000 connections operation"), + (bench_nested_query_pyodbc, bench_nested_query_mssql_python, "Nested query operation"), + (bench_large_data_set_pyodbc, bench_large_data_set_mssql_python, "Large data set operation"), + (bench_join_query_pyodbc, bench_join_query_mssql_python, "Join query operation"), + (bench_executemany_pyodbc, bench_executemany_mssql_python, "Execute many operation"), + (bench_100_inserts_pyodbc, bench_100_inserts_mssql_python, "1000 inserts operation"), + (bench_transaction_pyodbc, bench_transaction_mssql_python, "Transaction operation"), + (bench_update_with_join_pyodbc, bench_update_with_join_mssql_python, "Update with join operation"), + (bench_delete_with_join_pyodbc, bench_delete_with_join_mssql_python, "Delete with join operation"), +] \ No newline at end of file From 8007b68ea6b3cc09bec1826bb83467a1b636e4f8 Mon Sep 17 00:00:00 2001 From: gargsaumya Date: Wed, 23 Jul 2025 14:33:14 +0530 Subject: [PATCH 2/2] minor cleanup --- benchmarks/bench_mssql.py | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/benchmarks/bench_mssql.py b/benchmarks/bench_mssql.py index d8724f01..9aae0e56 100644 --- a/benchmarks/bench_mssql.py +++ b/benchmarks/bench_mssql.py @@ -162,26 +162,6 @@ def bench_complex_query_pyodbc(): except Exception as e: print(f"Error during COMPLEX QUERY benchmark: {e}") -def bench_multiple_connections_pyodbc(): - print("Running MULTIPLE CONNECTIONS benchmark with pyodbc...") - try: - connections = [] - for _ in range(10): - conn = pyodbc.connect(CONNECTION_STRING) - connections.append(conn) - - for conn in connections: - cursor = conn.cursor() - cursor.execute("SELECT * FROM perfbenchmark_table") - cursor.fetchall() - cursor.close() - - for conn in connections: - conn.close() - print("MULTIPLE CONNECTIONS benchmark with pyodbc completed.") - except Exception as e: - print(f"Error during MULTIPLE CONNECTIONS benchmark: {e}") - def bench_100_inserts_pyodbc(): print("Running 100 INSERTS benchmark with pyodbc...") try: @@ -679,7 +659,7 @@ def bench_1000_connections_mssql_python(): (bench_large_data_set_pyodbc, bench_large_data_set_mssql_python, "Large data set operation"), (bench_join_query_pyodbc, bench_join_query_mssql_python, "Join query operation"), (bench_executemany_pyodbc, bench_executemany_mssql_python, "Execute many operation"), - (bench_100_inserts_pyodbc, bench_100_inserts_mssql_python, "1000 inserts operation"), + (bench_100_inserts_pyodbc, bench_100_inserts_mssql_python, "100 inserts operation"), (bench_transaction_pyodbc, bench_transaction_mssql_python, "Transaction operation"), (bench_update_with_join_pyodbc, bench_update_with_join_mssql_python, "Update with join operation"), (bench_delete_with_join_pyodbc, bench_delete_with_join_mssql_python, "Delete with join operation"),