def pickJoinOrder(self, plan): rels = set(plan.relations()) optPlans = {} #Map a set of relations to the optimized plan #toBeProcessed = [] #Set of relations pending processing self.combsTried = 0 self.plansProcessed = 0 for r in rels: set_r = frozenset({r}) #toBeProcessed.append(set_r) newScan = TableScan(r, self.db.relationSchema(r)) newScan.prepare(self.db) optPlans[set_r] = newScan #For each join operator, fetch its relative relations #Map a set of relations to (relative relations, operator) joinMap = {} for (_, op) in plan.flatten(): if isinstance(op, Join): relativeR = self.relativeRelations(rels, op) for r in [frozenset({r}) for r in relativeR]: if r in joinMap.keys(): joinMap[r].append((relativeR, op)) else: joinMap[r] = [(relativeR, op)] n = len(rels) for i in range(2, n + 1): for union in [frozenset(union) for union in self.kRelsComb(i, rels)]: for right in [frozenset(right) for right in self.kRelsComb(1, union)]: left = frozenset(union - right) for t in left: self.combsTried += 1 value = joinMap[frozenset({t})] if not value: continue else: for tuple in value: if not (set(tuple[0]).issubset(union) and left in optPlans and right in optPlans): continue self.plansProcessed += 1 newJoin = Join(optPlans[left], optPlans[right], expr=tuple[1].joinExpr, method="block-nested-loops") newJoin.prepare(self.db) if not union in optPlans: optPlans[union] = newJoin self.addPlanCost(newJoin, newJoin.cost(estimated=True)) else: formerCost = self.getPlanCost(optPlans[union]) if newJoin.cost(estimated=True) < formerCost: optPlans[union] = newJoin self.addPlanCost(newJoin, newJoin.cost(estimated=True)) newRoot = optPlans[frozenset(rels)] return Plan(root=newRoot) '''
def processJoin(self, leftPlan, leftRels): newCost = None newJoin = None newRels = None for right in [frozenset({right}) for right in self.rels - leftRels]: value = self.joinMap[right] self.combsTried += 1 union = leftRels.union(right) if not value: continue else: for tuple in value: if not tuple[0].issubset(union): continue self.plansProcessed += 1 newJoin = Join(leftPlan, self.tableScans[right], expr=tuple[1].joinExpr, method="block-nested-loops") newJoin.prepare(self.db) newCost = newJoin.cost(estimated=True) newRels = frozenset(leftRels.union(right)) return (newCost, newJoin, newRels)