diff --git a/repositories/rules.go b/repositories/rules.go
index 6b35fa8ba..e0971324f 100644
--- a/repositories/rules.go
+++ b/repositories/rules.go
@@ -48,9 +48,11 @@ func (repo *MarbleDbRepository) ListRulesByIterationId(ctx context.Context, exec
 	)
 }
 
+// This method expects to be run in a transaction, because we set some local settings
+// that should not be changed for the whole connection.
 func (repo *MarbleDbRepository) RulesExecutionStats(
 	ctx context.Context,
-	exec Executor,
+	exec Transaction,
 	organizationId string,
 	iterationId string,
 	begin, end time.Time,
@@ -58,6 +60,17 @@ func (repo *MarbleDbRepository) RulesExecutionStats(
 	if err := validateMarbleDbExecutor(exec); err != nil {
 		return nil, err
 	}
+
+	// The following settings are set because in some cases at least, the query planner
+	// has ended up choosing a query plan involving a hash join with a full table scan on decision_rules
+	_, err := exec.Exec(ctx,
+		`SET local join_collapse_limit = 1;
+		SET local enable_hashjoin = off;
+		SET local enable_mergejoin = off;`)
+	if err != nil {
+		return nil, err
+	}
+
 	query := NewQueryBuilder().
 		Select("scir.stable_rule_id, scir.name, dr.outcome, scit.version, COUNT(*) as total").
 		From("decisions as d").
@@ -80,9 +93,11 @@ func (repo *MarbleDbRepository) RulesExecutionStats(
 	)
 }
 
+// This method expects to be run in a transaction, because we set some local settings
+// that should not be changed for the whole connection.
 func (repo *MarbleDbRepository) PhanomRulesExecutionStats(
 	ctx context.Context,
-	exec Executor,
+	exec Transaction,
 	organizationId string,
 	iterationId string,
 	begin, end time.Time,
@@ -90,6 +105,17 @@ func (repo *MarbleDbRepository) PhanomRulesExecutionStats(
 	if err := validateMarbleDbExecutor(exec); err != nil {
 		return nil, err
 	}
+
+	// The following settings are set because in some cases at least, the query planner
+	// has ended up choosing a query plan involving a hash join with a full table scan on decision_rules
+	_, err := exec.Exec(ctx,
+		`SET local join_collapse_limit = 1;
+		SET local enable_hashjoin = off;
+		SET local enable_mergejoin = off;`)
+	if err != nil {
+		return nil, err
+	}
+
 	query := NewQueryBuilder().
 		Select("scir.stable_rule_id, scir.name, dr.outcome, scit.version, COUNT(*) as total").
 		From("phantom_decisions as d").
diff --git a/usecases/rules_usecase.go b/usecases/rules_usecase.go
index fa7b0f116..673abd5b5 100644
--- a/usecases/rules_usecase.go
+++ b/usecases/rules_usecase.go
@@ -20,14 +20,14 @@ type RuleUsecaseRepository interface {
 	ListRulesByIterationId(ctx context.Context, exec repositories.Executor, iterationId string) ([]models.Rule, error)
 	RulesExecutionStats(
 		ctx context.Context,
-		exec repositories.Executor,
+		exec repositories.Transaction,
 		organizationId string,
 		iterationId string,
 		begin, end time.Time,
 	) ([]models.RuleExecutionStat, error)
 	PhanomRulesExecutionStats(
 		ctx context.Context,
-		exec repositories.Executor,
+		exec repositories.Transaction,
 		organizationId string,
 		iterationId string,
 		begin, end time.Time,
@@ -64,33 +64,38 @@ func (usecase *RuleUsecase) ListRules(ctx context.Context, iterationId string) (
 }
 
 func (usecase *RuleUsecase) ListRuleExecution(ctx context.Context, testrunId string) ([]models.RuleExecutionStat, error) {
-	exec := usecase.executorFactory.NewExecutor()
-	testrun, err := usecase.scenarioTestRunRepository.GetTestRunByID(ctx, exec, testrunId)
-	if err != nil {
-		return nil, err
-	}
-	rules, err := usecase.repository.PhanomRulesExecutionStats(
-		ctx,
-		exec,
-		testrun.OrganizationId,
-		testrun.ScenarioIterationId,
-		testrun.CreatedAt,
-		testrun.ExpiresAt)
-	if err != nil {
-		return nil, err
-	}
-	liveRules, err := usecase.repository.RulesExecutionStats(
-		ctx,
-		exec,
-		testrun.OrganizationId,
-		testrun.ScenarioLiveIterationId,
-		testrun.CreatedAt,
-		testrun.ExpiresAt)
-	if err != nil {
-		return nil, err
-	}
-	result := append(rules, liveRules...)
-	return result, nil
+	var result []models.RuleExecutionStat
+	err := usecase.transactionFactory.Transaction(ctx, func(tx repositories.Transaction) error {
+		testrun, err := usecase.scenarioTestRunRepository.GetTestRunByID(ctx, tx, testrunId)
+		if err != nil {
+			return err
+		}
+		rules, err := usecase.repository.PhanomRulesExecutionStats(
+			ctx,
+			tx,
+			testrun.OrganizationId,
+			testrun.ScenarioIterationId,
+			testrun.CreatedAt,
+			testrun.ExpiresAt)
+		if err != nil {
+			return err
+		}
+		result = append(result, rules...)
+
+		liveRules, err := usecase.repository.RulesExecutionStats(
+			ctx,
+			tx,
+			testrun.OrganizationId,
+			testrun.ScenarioLiveIterationId,
+			testrun.CreatedAt,
+			testrun.ExpiresAt)
+		if err != nil {
+			return err
+		}
+		result = append(result, liveRules...)
+		return nil
+	})
+	return result, err
 }
 
 func (usecase *RuleUsecase) CreateRule(ctx context.Context, ruleInput models.CreateRuleInput) (models.Rule, error) {