Merge pull request #2 from sandronator/claude/quizzical-haibt-fd6d93

Label output with Aufgabe + strategy + index config, fix lock hangs
This commit is contained in:
Sandro Fuetsch
2026-05-26 21:07:55 +02:00
committed by GitHub
6 changed files with 52 additions and 51 deletions
+16 -11
View File
@@ -12,30 +12,35 @@ class BaseStrategy:
self.cursor = conn.cursor() self.cursor = conn.cursor()
self.db_name = db_name self.db_name = db_name
self.queries = queries self.queries = queries
self.BASENAME = "Base " self.index_config = None # vom Manager via setup_db gesetzt
self.strategy_name = self.BASENAME
def set_queries(self, queries): def set_queries(self, queries):
self.queries = queries self.queries = queries
def set_strategy(self, name: str): def run(self, aufgabe: str | None = None):
self.strategy_name = self.BASENAME + name strategy_name = self.__class__.__name__
prefix_parts = []
if aufgabe:
prefix_parts.append(aufgabe)
prefix_parts.append(strategy_name)
if self.index_config:
prefix_parts.append(f"idx={self.index_config}")
prefix = " | ".join(prefix_parts)
def run(self): for query_name, query in self.queries.items():
for strategy, query in self.queries.items(): print(f"Running: [{prefix}] / {query_name}\n")
print("Running: " + self.strategy_name + "\n")
start = time.time() start = time.time()
self.cursor.execute(query) self.cursor.execute(query)
end = time.time() end = time.time()
self._print_result(strategy, end, start) self._print_result(query_name, end, start, prefix)
def _print_result(self, strategy, end, start): def _print_result(self, query_name, end, start, prefix):
duration = end - start duration = end - start
minutes= int(duration // 60) minutes = int(duration // 60)
seconds = duration % 60 seconds = duration % 60
print(f"---- RESULTS FROM {self.db_name} Strategy: {strategy} ----\n") print(f"---- RESULTS FROM {self.db_name} | {prefix} | Query: {query_name} ----\n")
print(f"duration: {minutes}m {seconds:.2f}s") print(f"duration: {minutes}m {seconds:.2f}s")
_print_cursor(self.cursor) _print_cursor(self.cursor)
+2 -2
View File
@@ -7,14 +7,14 @@ class HashJoinStrategy(BaseStrategy):
super().__init__(conn, db_name, all_queries) super().__init__(conn, db_name, all_queries)
def run(self): def run(self, aufgabe: str | None = None):
if self.db_name not in resolve: if self.db_name not in resolve:
raise Exception("Hash Join not supported for " + self.db_name) raise Exception("Hash Join not supported for " + self.db_name)
for disable in resolve[self.db_name]["disable"]: for disable in resolve[self.db_name]["disable"]:
self.cursor.execute(disable) self.cursor.execute(disable)
super().run() super().run(aufgabe=aufgabe)
for reset in resolve[self.db_name]["reset"]: for reset in resolve[self.db_name]["reset"]:
self.cursor.execute(reset) self.cursor.execute(reset)
+13 -19
View File
@@ -8,6 +8,9 @@ from repositories.all_queries import queries_postgres
if __name__ == '__main__': if __name__ == '__main__':
db_post, conn_postsql = get_connection(maria=False) db_post, conn_postsql = get_connection(maria=False)
# Autocommit verhindert, dass EXPLAIN ANALYZE Locks (AccessShareLock auf publ/auth)
# bis zum naechsten Commit haelt -- sonst blockiert das spaeter DROP INDEX/CLUSTER.
conn_postsql.autocommit = True
# Daten einmalig laden; danach werden zwischen den Tests nur die Indexe getauscht. # Daten einmalig laden; danach werden zwischen den Tests nur die Indexe getauscht.
load_data_postgres() load_data_postgres()
@@ -15,42 +18,33 @@ if __name__ == '__main__':
# Aufgabe 1 # Aufgabe 1
join_manager = Manager(BaseStrategy(conn_postsql, db_post, queries_postgres["with_index"])) join_manager = Manager(BaseStrategy(conn_postsql, db_post, queries_postgres["with_index"]))
# join_manager.setup_db("no-index") # join_manager.setup_db("no-index")
# join_manager.execute() # 3 Billionen. Tupel via Kreuzprodukt -> > 10 min # join_manager.execute(aufgabe="Aufgabe 1a") # 3 Mrd. Tupel via Kreuzprodukt -> > 10 min
join_manager.setup_db("unique-publ") join_manager.setup_db("unique-publ")
join_manager.setStrategyName("unique-publ") join_manager.execute(aufgabe="Aufgabe 1b")
join_manager.execute()
join_manager.setup_db("cl-both") join_manager.setup_db("cl-both")
join_manager.setStrategyName("cl-both") join_manager.execute(aufgabe="Aufgabe 1c")
join_manager.execute()
# Aufgabe 2 # Aufgabe 2
# reload_data=True stellt die ursprüngliche Ladereihenfolge wieder her. # reload_data=True stellt die ursprüngliche Ladereihenfolge wieder her.
join_manager.setStrategy(NestedInnerLoopStrategy(conn_postsql, db_post, queries_postgres["with_index"])) join_manager.setStrategy(NestedInnerLoopStrategy(conn_postsql, db_post, queries_postgres["with_index"]))
join_manager.setup_db("nc-publ", reload_data=True) join_manager.setup_db("nc-publ", reload_data=True)
join_manager.setStrategyName("nc-publ") join_manager.execute(aufgabe="Aufgabe 2a")
join_manager.execute()
join_manager.setup_db("nc-auth") join_manager.setup_db("nc-auth")
join_manager.setStrategyName("nc-auth") join_manager.execute(aufgabe="Aufgabe 2b")
join_manager.execute()
join_manager.setup_db("nc-both") join_manager.setup_db("nc-both")
join_manager.setStrategyName("nc-both") join_manager.execute(aufgabe="Aufgabe 2c")
join_manager.execute()
# Aufgabe 3 # Aufgabe 3
join_manager.setStrategy(SortMergeStrategy(conn_postsql, db_post, queries_postgres["no_index"])) join_manager.setStrategy(SortMergeStrategy(conn_postsql, db_post, queries_postgres["no_index"]))
join_manager.setup_db("no-index") join_manager.setup_db("no-index")
join_manager.setStrategyName("no-index") join_manager.execute(aufgabe="Aufgabe 3a")
join_manager.execute()
join_manager.setQueries(queries_postgres["with_index"]) join_manager.setQueries(queries_postgres["with_index"])
join_manager.setup_db("nc-both") join_manager.setup_db("nc-both")
join_manager.setStrategyName("nc-both") join_manager.execute(aufgabe="Aufgabe 3b")
join_manager.execute()
join_manager.setup_db("cl-both") join_manager.setup_db("cl-both")
join_manager.setStrategyName("cl-both") join_manager.execute(aufgabe="Aufgabe 3c")
join_manager.execute()
# Aufgabe 4 — wieder vom CLUSTER-Zustand wegkommen. # Aufgabe 4 — wieder vom CLUSTER-Zustand wegkommen.
join_manager.setStrategy(HashJoinStrategy(conn_postsql, db_post, queries_postgres["no_index"])) join_manager.setStrategy(HashJoinStrategy(conn_postsql, db_post, queries_postgres["no_index"]))
join_manager.setup_db("no-index", reload_data=True) join_manager.setup_db("no-index", reload_data=True)
join_manager.setStrategyName("nc-publ") join_manager.execute(aufgabe="Aufgabe 4")
join_manager.execute()
+7 -5
View File
@@ -4,20 +4,22 @@ import setup
class Manager: class Manager:
def __init__(self, strategy: BaseStrategy, ): def __init__(self, strategy: BaseStrategy, ):
self.strategy = strategy self.strategy = strategy
self.current_index_config = None
def setStrategy(self, strategy: BaseStrategy): def setStrategy(self, strategy: BaseStrategy):
self.strategy = strategy self.strategy = strategy
# Aktuellen Index-Config an die neue Strategy weiterreichen
def setStrategyName(self, name: str): self.strategy.index_config = self.current_index_config
self.strategy.set_strategy(name)
def setQueries(self, queries: dict[str, str]): def setQueries(self, queries: dict[str, str]):
self.strategy.set_queries(queries) self.strategy.set_queries(queries)
# Only Postgresql and MariaDb available at the moment # Only Postgresql and MariaDb available at the moment
def setup_db(self, index_config, reload_data=False): def setup_db(self, index_config, reload_data=False):
self.current_index_config = index_config
self.strategy.index_config = index_config
setup.reset_postgres(index_config, reload_data=reload_data) setup.reset_postgres(index_config, reload_data=reload_data)
def execute(self): def execute(self, aufgabe: str | None = None):
self.strategy.run() self.strategy.run(aufgabe=aufgabe)
+2 -2
View File
@@ -6,14 +6,14 @@ class NestedInnerLoopStrategy(BaseStrategy):
self.BASENAME = "Nested Inner Loop " self.BASENAME = "Nested Inner Loop "
super().__init__(conn, db_name, all_queries) super().__init__(conn, db_name, all_queries)
def run(self): def run(self, aufgabe: str | None = None):
if self.db_name not in resolve: if self.db_name not in resolve:
raise Exception("No Inner Loop Resolver Found") raise Exception("No Inner Loop Resolver Found")
for disable in resolve[self.db_name]["disable"]: for disable in resolve[self.db_name]["disable"]:
self.cursor.execute(disable) self.cursor.execute(disable)
super().run() super().run(aufgabe=aufgabe)
for reset in resolve[self.db_name]["reset"]: for reset in resolve[self.db_name]["reset"]:
self.cursor.execute(reset) self.cursor.execute(reset)
+2 -2
View File
@@ -6,14 +6,14 @@ class SortMergeStrategy(BaseStrategy):
self.BASENAME = "Sort Merge " self.BASENAME = "Sort Merge "
super().__init__(conn, db_name, all_queries) super().__init__(conn, db_name, all_queries)
def run(self): def run(self, aufgabe: str | None = None):
if self.db_name not in resolve: if self.db_name not in resolve:
raise Exception("Sort-Merge Join not supported for " + self.db_name) raise Exception("Sort-Merge Join not supported for " + self.db_name)
for disable in resolve[self.db_name]["disable"]: for disable in resolve[self.db_name]["disable"]:
self.cursor.execute(disable) self.cursor.execute(disable)
super().run() super().run(aufgabe=aufgabe)
for reset in resolve[self.db_name]["reset"]: for reset in resolve[self.db_name]["reset"]:
self.cursor.execute(reset) self.cursor.execute(reset)