Files
secondo/Optimizer/nawra.pl
2026-01-23 17:03:45 +08:00

1128 lines
32 KiB
Prolog

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [10] title: [{\Large \bf ] [}]
//characters [1] formula: [$] [$]
//[ae] [\"{a}]
//[oe] [\"{o}]
//[ue] [\"{u}]
//[ss] [{\ss}]
//[Ae] [\"{A}]
//[Oe] [\"{O}]
//[Ue] [\"{U}]
//[**] [$**$]
//[star] [$*$]
//[=>] [\verb+=>+]
//[toc] [\tableofcontents]
//[newpage] [\newpage]
Diploma thesis
[10] Precise Cost Estimation in the SECONDO extensible Database System
Author: Artur Nawra, March 2006 \newline
Modified: Christian D[ue]ntgen, June 2006
[toc]
[newpage]
1 File ~DatabaseN.pl~
The file was merged with file ~database.pl~.
2 File ~costnew.pl~
*/
/*
Determine the assessed costs of an input term using rules ~cost\_new~. Then charge the total costs by applying rule ~costtotal~.
*/
costterm(Term, Sel, Source, Result, Size, CostTotal) :-
( optimizerOption(nawracosts)
-> ( costnew(Term, Sel, Source, Result, Size, TupleSize, Cost),
setNodeTupleSize(Result, TupleSize),
costtotal(Cost, CostTotal)
)
; throw(error_Internal(nawra_costterm(Term, Sel, Source, Result, Size,
CostTotal)::should_not_be_called_without_option_nawracosts))
).
/*
Calculates the total costs of a term considering the calibration factors.
*/
costtotal(Cost, CostTotal) :-
vCostFactorCPU(V),
wCostFactor(W),
CostCal is Cost * V,
CostTotal is CostCal * W.
/*
Calculates the costs for a term under consideration for the calibration factor.
*/
costCal(Cost, CostCal) :-
vCostFactorCPU(V),
CostCal is Cost * V.
/*
The new rules for the cost estimation. The cost estimation for an input term goes
recursively. The arguments are: ~Term~, ~Sel~, ~Source~ and ~Result~. ~term~ is
an executable plan of an edge in the POG. ~Sel~ is its selectivity. The variables
~Source~ and ~Result~ contain the node number of the considered edge in the
POG. The remaining variables are the return value straps. ~Size~ is the tuple
number, ~TupleSize~ is the tuple size term, ~Cost~ is the assessed costs of the input term. Cost factors are used in all functions. The cost factors are contained in corresponding clauses of the form ~storedOperatorTF~.
*/
/*
Cost estimation for arguments. The arguments can be relations or intermediate
results.
*/
costnew(rel(Rel,_), _, _, _, Size, TupleSize, 0) :-
card(Rel, Size),
tupleSizeSplit(Rel, TupleSize), !.
costnew(res(N), _, _, _, Size, TupleSize, 0) :-
resultSize(N, Size),
nodeTupleSize(N, TupleSize), !.
/*
Cost estimation for operator feed.
*/
costnew(feed(X), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(feed, A, B),
Size is SizeX,
TupleSize = TupleSizeX,
TupleSize = sizeTerm(Core,Inflob,_),
Cost is CostX + (A * (Core+Inflob) + B) * SizeX, !.
/*
Cost estimation for operator consume.
*/
costnew(consume(X), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(consume, A, B),
Size is SizeX,
TupleSize = TupleSizeX,
TupleSize = sizeTerm(X1,X2,X3),
Cost is CostX + (A * (X1+X2+X3) + B) * SizeX, !.
/*
Cost for operator filter. The costs of predicates are taken account of.
For ~filter~, there are several special cases to distinguish:
1 ~filter(spatialjoin(...),P)~
2 ~filter(gettuples(...),P)~
3 ~filter(windowintersects(...),P)~
4 ``normal'' ~filter(...)~
For the first three cases, the edge is the translation of a spatial predicate, that
makes use of bounding box checks. The first argument of filter will already reduce
the set of possible candidates, so that the cardinality of tuples processed by filter
will be smaller than the cardinality passed down in the 3rd argument of ~cost~. Also, the
selectivity passed with the second argument of ~cost~ if the ~total~ selectivity. To
get the selectivity of the preselection, one can analyse the predicate and lookup
the table ~storedBBoxSel/3~ for that selectivity, which should be passed to the recursive
call of ~cost~.
PROBLEM: What happens with the entropy-optimizer? As for cases 2 + 3, there is no
problem, as the index is used to create a fresh tuple stream. But, as for case 1, we
might get into problems, as the selectivity of the bbox-check depends on earlier
predicates - so we should consider both selectivities in the minimization of the entropy.
*/
costnew(filter(X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
term_to_atom(X, XAtom),
atom_prefix(XAtom, 'spatialjoin'),
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
getEdgePredCost(Source, Result, PredCost),
% filterTC(A),
Size is SizeX,
TupleSize = TupleSizeX,
Cost is CostX + PredCost * SizeX, !.
costnew(filter(X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
getEdgePredCost(Source, Result, PredCost),
% filterTCnew(A),
Size is SizeX * Sel,
TupleSize = TupleSizeX,
Cost is CostX + PredCost * SizeX, !.
/*
Cost estimation for operator product.
*/
costnew(product(X, Y), _, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
costnew(Y, 1, Source, Result, SizeY, TupleSizeY, CostY),
storedOperatorTF(producta, A1, B1),
storedOperatorTF(productb, A2, B2),
producttest(SizeY, TupleSizeY, C1),
Size is SizeX * SizeY,
addSizeTerms([TupleSizeX,TupleSizeY],TupleSize),
TupleSizeX = sizeTerm(X1,X2,X3),
TupleSizeY = sizeTerm(Y1,Y2,Y3),
Cost is CostX + CostY + SizeX * ((X1+X2+X3) * A1 + B1)
* SizeY * ((Y1+Y2+Y3) * A2 + B2) * C1, !.
/*
Cost estimation for operator loopjoin.
*/
costnew(loopjoin(X, Y), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
costnew(Y, Sel, Source, Result, SizeY, TupleSizeY, CostY),
storedOperatorTF(loopjoin, A2, B2),
storedOperatorTF(concatenationflob, A3, _),
% getEdgePredCost(Source, Result, _, PredCostET),
Size is SizeX * SizeY,
addSizeTerms([TupleSizeX,TupleSizeY],TupleSize),
TupleSizeX = sizeTerm(X1,X2,X3),
TupleSizeY = sizeTerm(Y1,Y2,Y3),
FlobSize is X3+Y3,
Cost is CostX + SizeX * CostY
+ ((A2 * (X1+X2 + Y1+Y2) + B2) + (A3 * FlobSize)) * Size, !.
/*
Cost estimation for operator fun.
*/
costnew(fun(_, X), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, Size, TupleSize, Cost), !.
/*
Cost estimate for operator hashjoin.
Several aspects are taken into account:
* the number of the evaluations of the Join condition,
* the costs for the possible on-disk buffering of the first argument
* the costs of the concatenation of the suitable tuples.
*/
costnew(hashjoin(X, Y, _, _, NBuckets), Sel, Source,
Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
costnew(Y, 1, Source, Result, SizeY, TupleSizeY, CostY),
storedOperatorTF(hashtab, A, _),
storedOperatorTF(concatenationjoin, A2, B2),
storedOperatorTF(concatenationflob, A3, _),
getEdgePredCost(Source, Result, PredCost),
predEvalNumber(SizeX, SizeY, NBuckets, PredNr),
tempRelCost(SizeX, TupleSizeX, SizeY, TupleSizeY, TempCost),
Size is SizeX * SizeY * Sel,
addSizeTerms([TupleSizeX,TupleSizeY],TupleSize),
TupleSizeX = sizeTerm(X1,X2,X3),
TupleSizeY = sizeTerm(Y1,Y2,Y3),
FlobSize is X3 + Y3,
Cost is CostX + CostY + (PredCost + A) * PredNr + TempCost
+ ((A2 * (X1+X2 + Y1+Y2) + B2) + (A3 * FlobSize)) * Size, !.
/*
Cost estimation for operator sortmergejoin.
Several aspects are taken into account:
* the number of the evaluations of the Join condition,
* the costs for the sorting of the arguments,
* the costs of the concatenation of the suitable tuples.
The following rule has been replaced by a rule calling the rules for sortby and mergejoin,
please see below.
----
costnew(sortmergejoin(X, Y, _, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
costnew(Y, 1, Source, Result, SizeY, TupleSizeY, CostY),
storedOperatorTF(concatenationjoin, A2, B2),
storedOperatorTF(concatenationflob, A3, _),
getEdgePredCost(Source, Result, PredCost),
sortcost(TupleSizeX, SizeX, SortCostX),
sortcost(TupleSizeY, SizeY, SortCostY),
Size is SizeX * SizeY * Sel,
addSizeTerms([TupleSizeX,TupleSizeY],TupleSize),
TupleSizeX = sizeTerm(X1,X2,X3),
TupleSizeY = sizeTerm(Y1,Y2,Y3),
FlobSize is X3 + Y3,
Cost is CostX + CostY + SortCostX + SortCostY
+ PredCost * (SizeX + SizeY)
+ ((A2 * (X1+X2 + Y1+Y2) + B2) + (A3 * FlobSize)) * Size.
----
*/
/*
Cost estimation for operator extend. The costs for the compution of the value of the new attribute are taken into account.
*/
costnew(extend(X, Term), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(extend, A, _),
Size is SizeX,
attrlistExtend(Term, ExtendSize, TermCost),
addSizeTerms([TupleSizeX,ExtendSize],TupleSize),
Cost is CostX + A * SizeX + TermCost * SizeX, !.
/*
Cost estimation for operator remove.
*/
costnew(remove(X, L), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(remove, A, _),
Size is SizeX,
attrlistRemove(L, RemoveSize),
addSizeTerms([TupleSizeX,RemoveSize],TupleSize),
Cost is CostX + A * SizeX, !.
/*
Cost estimation for operator rename.
*/
costnew(rename(X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(rename, A, _),
Size is SizeX,
TupleSize = TupleSizeX,
Cost is CostX + A * SizeX, !.
/*
Cost estimation for operator leftrange.
*/
costnew(leftrange(_, X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(leftrange, A, B),
getEdgePredCost(Source, Result, PredCost),
Size is SizeX * Sel,
TupleSize = TupleSizeX,
TupleSizeX = sizeTerm(Core, InFlob, _),
Cost is CostX + PredCost * Size + (A * (Core + InFlob) + B) * Size, !.
/*
Cost estimation for operator rightrange.
*/
costnew(rightrange(_, X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(leftrange, A, B),
getEdgePredCost(Source, Result, PredCost),
Size is SizeX * Sel,
TupleSize = TupleSizeX,
TupleSizeX = sizeTerm(Core, InFlob, _),
Cost is CostX + PredCost * Size + (A * (Core + InFlob) + B) * Size, !.
/*
Cost estimation for operator exactmatchfun.
*/
costnew(exactmatchfun(_, X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(exactmatchfun, A, B),
getEdgePredCost(Source, Result, PredCost),
Size is SizeX * Sel,
TupleSize = TupleSizeX,
TupleSizeX = sizeTerm(Core, InFlob, _),
Cost is CostX + PredCost * Size + (A * (Core + InFlob) + B) * Size, !.
/*
Cost estimation for operator exactmatch.
*/
costnew(exactmatch(_, X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(exactmatch, A, B),
getEdgePredCost(Source, Result, PredCost),
Size is SizeX * Sel,
TupleSize = TupleSizeX,
TupleSize = sizeTerm(Core, InFlob, _),
Cost is CostX + PredCost * Size + (A * (Core + InFlob) + B) * Size, !.
/*
Cost estimation for operator windowintersects.
*/
costnew(windowintersects(_, X, _), Sel, Source, Result,
Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
storedOperatorTF(windowintersects, A, B),
Size is Sel * SizeX,
TupleSize = TupleSizeX,
TupleSize = sizeTerm(Core, InFlob, _),
Cost is CostX + (A * (Core + InFlob) + B) * Size, !.
/*
Cots estimation for operator windowintersectsS.
*/
% Cost function not verified:
costnew(windowintersectsS(IndexName, _), Sel, Source, Result,
Size, sizeTerm(12,0,0), Cost) :- % constant tuplesize for [tid]
% get relationName Rel from Index
my_concat_atom([RelName|_],'_',IndexName),
Rel = rel(RelName, *),
costnew(Rel, 1, Source, Result, RelSize, TupleSize, _),
asserta(storedWindowIntersectsS(TupleSize)), % store tuplesize for gettuples
storedOperatorTF(windowintersects, A, B),
Size is Sel * RelSize,
Cost is (A * 12 + B) * RelSize, !. % returns a stream of tids
/*
Cost estimation for operator gettuples
*/
% Cost function not verified:
costnew(gettuples(X, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, _, CostX),
storedWindowIntersectsS(TupleSize),
% get tuplesize stored by windowintersectsS
retract(storedWindowIntersectsS(TupleSize)),
storedOperatorTF(feed, A, B),
TupleSize = sizeTerm(Core, InFlob, _),
Size is SizeX,
Cost is CostX + (A * (Core + InFlob) + B) * SizeX, !.
/*
Cost estimation for operator project
*/
costnew(project(X, Arg), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, _, CostX),
attrlistSize(Arg, ArgTupleSize),
TupleSize = ArgTupleSize,
Size is SizeX,
Cost is CostX, !.
/*
Cost estimation for operator symmjoin
*/
costnew(symmjoin(X, Y, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
costnew(Y, 1, Source, Result, SizeY, TupleSizeY, CostY),
storedOperatorTF(concatenationjoin, A2, B2),
storedOperatorTF(concatenationflob, A3, _),
getEdgePredCost(Source, Result, PredCost),
tempRelCostsymmjoin(SizeX, TupleSizeX, SizeY, TupleSizeY, TempCost),
Size is SizeX * SizeY * Sel,
addSizeTerms([TupleSizeX,TupleSizeY], TupleSize),
TupleSizeX = sizeTerm(CoreX, InFlobX, ExtFlobX),
TupleSizeY = sizeTerm(CoreY, InFlobY, ExtFlobY),
FlobSize is ExtFlobX + ExtFlobY,
TupleSizeExt is CoreX + CoreY + InFlobX + InFlobY,
Cost is CostX + CostY + PredCost * (SizeX * SizeY) + TempCost
+ ((A2 * TupleSizeExt + B2) + (A3 * FlobSize)) * Size, !.
/*
Cost estimation for operator spatialjoin
*/
costnew(spatialjoin(X, Y, _, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
costnew(Y, 1, Source, Result, SizeY, TupleSizeY, CostY),
storedOperatorTF(concatenationjoin, A2, B2),
storedOperatorTF(concatenationflob, A3, _),
storedOperatorTF(spatialjoinx, A1x, B1x),
storedOperatorTF(spatialjoiny, A1y, B1y),
% getEdgePredCost(Source, Result, PredCost),
Size is SizeX * SizeY * Sel,
addSizeTerms([TupleSizeX,TupleSizeY], TupleSize),
TupleSizeX = sizeTerm(CoreX, InFlobX, ExtFlobX),
TupleSizeY = sizeTerm(CoreY, InFlobY, ExtFlobY),
FlobSize is ExtFlobX + ExtFlobY,
TupleSizeExt is CoreX + CoreY + InFlobX + InFlobY,
TotalTupleSizeX is CoreX + InFlobX + ExtFlobX,
TotalTupleSizeY is CoreY + InFlobY + ExtFlobY,
Cost is CostX + CostY
+ ((SizeX * log(SizeX + 1) * TotalTupleSizeX * A1x)
+ (SizeX^2 * TotalTupleSizeX * B1x)) /2
+ ((SizeY * log(SizeY + 1) * TotalTupleSizeY * A1y)
+ (SizeY^2 * TotalTupleSizeY * B1y)) /2
+ ((A2 * TupleSizeExt + B2) + (A3 * FlobSize)) * Size, !.
/*
Cost estimation for operator consume
*/
costnew(consume(X), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
consumeTC(A),
Cost is CostX + A * Size,
Size is SizeX,
TupleSize = TupleSizeX, !.
/*
For operator pjoin, only dummy functions are implemented:
*/
costnew(pjoin2(_, _, [ _ | _ ]), Sel, _, _, Sel, _, Cost) :-
Cost is 1, !.
costnew(pjoin1(_, _, [ _ | _ ]), Sel, _, _, Sel, _, Cost) :-
Cost is 0, !.
/*
Cost estimation for operator rdup
*/
% Cost function not verified:
costnew(rdup(X), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSize, Cost1),
sortcost(TupleSize, SizeX, CostRDUP),
Size is SizeX,
Cost is Cost1 + CostRDUP, !.
/*
Cost estimation for operator sort
*/
costnew(sort(X), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, Sel, Source, Result, SizeX, TupleSizeX, CostX),
sortcost(TupleSizeX, SizeX, SortCost),
TupleSize = TupleSizeX,
Size is SizeX,
Cost is CostX + SortCost, !.
/*
Cost estimation for operator sortby
*/
costnew(sortby(X, _), Sel, Source, Result, S, TupleSize, C) :-
costnew(sort(X), Sel, Source, Result, S, TupleSize, C), !.
/*
Cost estimation for operator mergejoin
*/
costnew(mergejoin(X, Y, _, _), Sel, Source, Result, Size, TupleSize, Cost) :-
costnew(X, 1, Source, Result, SizeX, TupleSizeX, CostX),
costnew(Y, 1, Source, Result, SizeY, TupleSizeY, CostY),
storedOperatorTF(concatenationjoin, A2, B2),
storedOperatorTF(concatenationflob, A3, _),
getEdgePredCost(Source, Result, PredCost),
Size is SizeX * SizeY * Sel,
addSizeTerms([TupleSizeX,TupleSizeY],TupleSize),
TupleSizeX = sizeTerm(X1,X2,X3),
TupleSizeY = sizeTerm(Y1,Y2,Y3),
FlobSize is X3 + Y3,
Cost is CostX + CostY
+ PredCost * (SizeX + SizeY)
+ ((A2 * (X1+X2 + Y1+Y2) + B2) + (A3 * FlobSize)) * Size, !.
/*
Cost estimation for operator sortmergejoin
*/
costnew(sortmergejoin(X, Y, AX, AY), Sel, Source, Result, S, TS, C) :-
costnew(mergejoin(sortby(X, [AX]),sortby(Y, [AY]), AX, AY),
Sel, Source, Result, S, TS, C), !.
% two rules used by the 'interesting orders extension':
costnew(sortLeftThenMergejoin(X, Y, AX, AY), Sel, Source, Target, S, TS, C) :-
costnew(mergejoin(sortby(X, [AX]), Y, AX, AY), Sel, Source, Target, S, TS, C),
!.
costnew(sortRightThenMergejoin(X, Y, AX, AY), Sel, Source, Target, S, TS, C) :-
costnew(mergejoin(X, sortby(Y, [AY]), AX, AY), Sel, Source, Target, S, TS, C),
!.
/*
Predicates auxiliary to cost:
---- gsf(M, N, S)
log(B, V, R)
----
These predicates calculate $S=\sum_{i=1}^{N-M}{i+M} = {{(N-M)(N+M+1)}\over{2}}$
and $R = log_B V$.
*/
:- arithmetic_function(log/2).
log(Base, Value, Result) :-
Result is log(Value) / log(Base).
/*
Rules to estimation costs for internal and external sorting.
*/
sortcost(TupleSize, Size, Cost) :-
TupleSize = sizeTerm(Core, InFlob, _),
secOptConstant(bufferSize, Memory),
V is (Core + InFlob) * Size,
Memory > V,
storedOperatorTF(intsort, A1, B1),
Cost is Size * log(Size) * (A1 * (Core + InFlob) + B1),
% Should be:
% Cost is Size * log(Size) * (A1 * (Core + InFlob) + B1),
!.
sortcost(TupleSize, Size, Cost) :-
TupleSize = sizeTerm(Core, InFlob, _),
TupleSizeExt is Core + InFlob,
secOptConstant(bufferSize, Memory),
storedOperatorTF(intsort, A1, B1),
storedOperatorTF(extsort, A2, B2),
PSize is Memory / TupleSizeExt,
L is Size / PSize,
Cost is Size * log(PSize) * (A1 * TupleSizeExt + B1)
+ Size * log(L) * 1.44 * (A2 * TupleSizeExt + B2),
% Should be:
% L is Size / (2 * PSize),
% Cost is Size * log(2,PSize) * (A1 * TupleSizeExt + B1)
% + Size * log(2,L) * 1.44 * (A2 * TupleSizeExt + B2),
!.
/*
Estimating the number of evaluations of a predicate during the hashjoin.
*/
predEvalNumber(SizeX, SizeY, NBuckets, PredNr) :-
NBuckets > SizeY,
PredNr is SizeX, !.
predEvalNumber(SizeX, SizeY, NBuckets, PredNr) :-
PredNr is SizeX * (SizeY / NBuckets), !.
/*
Cost estimation for temporary storing an argument during the hashjoin.
*/
tempRelCost(SizeX, TupleSizeX, SizeY, TupleSizeY, TempCost) :-
TupleSizeX = sizeTerm(X1,X2,_),
TupleSizeY = sizeTerm(Y1,Y2,_),
TupleSizeExtX is X1 + X2,
TupleSizeExtY is Y1 + Y2,
secOptConstant(bufferSize, Memory),
PSizeX is (Memory * 0.25) / TupleSizeExtX,
PSizeY is (Memory * 0.75) / TupleSizeExtY,
PSizeX < SizeX,
PSizeY < SizeY,
storedOperatorTF(hashtemp, A1, B1),
storedOperatorTF(hashcachecal, A2, B2),
TempRelSize is SizeX - PSizeX,
HashTabNr is SizeY / (Memory * 0.75) * (TupleSizeExtY * A2 + B2),
TempCost is TempRelSize * (TupleSizeExtX * A1 + B1) * (HashTabNr + 1),
!.
tempRelCost(_, _, _, _, 0).
tempRelCostsymmjoin(SizeX, TupleSizeX, SizeY, TupleSizeY, TempCost) :-
secOptConstant(bufferSize, Memory),
TupleSizeX = sizeTerm(CoreX, InFlobX, _),
TupleSizeY = sizeTerm(CoreY, InFlobY, _),
PSizeX is (Memory * 0.5) / (CoreX + InFlobX),
PSizeX < SizeX,
storedOperatorTF(hashtemp, A1, B1),
storedOperatorTF(hashcachecal, A2, B2),
TempRelSize is SizeX - PSizeX,
Inter is SizeY * ((CoreY + InFlobY) * A2 + B2),
TempCost is TempRelSize * ((CoreX + InFlobX) * A1 + B1) * (Inter + 1),
!.
tempRelCostsymmjoin(SizeX, TupleSizeX, SizeY, TupleSizeY, TempCost) :-
secOptConstant(bufferSize, Memory),
TupleSizeX = sizeTerm(CoreX, InFlobX, _),
TupleSizeY = sizeTerm(CoreY, InFlobY, _),
PSizeY is (Memory * 0.5) / (CoreY + InFlobY),
PSizeY < SizeY,
storedOperatorTF(hashtemp, A1, B1),
storedOperatorTF(hashcachecal, A2, B2),
TempRelSize is SizeY - PSizeY,
Inter is SizeX * ((CoreX + InFlobX) * A2 + B2),
TempCost is TempRelSize * ((CoreY + InFlobY) * A1 + B1) * (Inter + 1),
!.
tempRelCostsymmjoin(_, _, _, _, 0) :- !.
/*
Test for buffer overflow in operator product.
*/
producttest(Size, TupleSize, CF) :-
TupleSize = sizeTerm(Core,Inflob,Extflob),
secOptConstant(bufferSize, Memory),
V is Size * (Core+Inflob+Extflob),
V > Memory,
CF is 1,
!.
producttest(_, _, CF) :-
storedOperatorTF(productc, CF, _), !.
/*
Return the argument, if it is positive. Otherwise return 0.
*/
notnegativ(Zahl, Zahl) :- Zahl >= 0, !.
notnegativ(_, 0) :- !.
/*
Return the estimated cost of a single application of the predicate belonging
to the POG-egde (Source Result).
XRIS: The choosing of PET type should become more intelligent!
*/
getEdgePredCost(Source, Target, PET) :-
getPredNoPET(Source, Target, _, PET), !. % chooce calculated PETs
% getPredNoPET(Source, Target, PET, _), !. % choose mesured PETs
/*
The clauses test, if a number (attribute size) is smaller than 1000.
*/
sizeKlass(Size, Size, Size) :- Size < 1000, !.
sizeKlass(Size, 0, Size) :- !.
/*
Rules calculating tuple size after applying operator project.
The clauses have been moved to file ``database.pl''.
*/
/*
Calculate the joint attribute size (tuple size) after execution of
the extend operator as well as the costs, which are connected to the expansion.
---- attrlistExtend(+AttrList, -TupleSize, -Cost)
----
The clauses use a dynamic predicate ~storedExtendAttrSize/2~ to store
information on extension attributes.
---- attrlistRemove(+AttrList, Size)
----
Calculates the joint attribute sizes for list ~AttrList~ and multiplies it by -1
*/
attrlistExtend([X], Size, Cost) :-
attrlistExtend(X, Size, Cost), !.
attrlistExtend([X|Xs], Size, Cost) :-
attrlistExtend(X, SizeX, CostX),
attrlistExtend(Xs, SizeXs, CostXs),
addSizeTerms([SizeX,SizeXs],Size),
Cost is CostX + CostXs, !.
attrlistExtend(newattr(Attr, Term), Size, Cost) :-
simpleTerm(Term, STerm, Size),
setExtendAttrSize(Attr, Size),
extendSTermCost(STerm, Cost), !.
setExtendAttrSize(attrname(attr(Attr, Arg, Case)), Size) :-
storedExtendAttrSize(attrname(attr(Attr, _, _)), _, _),
retract(storedExtendAttrSize(attrname(attr(Attr, _, _)), _)),
assert(storedExtendAttrSize(attrname(attr(Attr, Arg, Case)), Size)),
!.
setExtendAttrSize(Attr, Size) :-
assert(storedExtendAttrSize(Attr, Size)), !.
resExtendAttrSize(Attr, Size) :-
storedExtendAttrSize(Attr, Size), !.
attrlistRemove([], sizeTerm(0,0,0)) :- !.
attrlistRemove([X|Xs], Size) :-
attrlistRemove(X, SizeX),
attrlistRemove(Xs, SizeXs),
addSizeTerms([SizeX,SizeXs],Size), !.
% special case: TupleIDs in _small relations
attrlistRemove(X, sizeTerm(-12,0,0)) :-
( X = attrname(attr(_:Attr, _, _))
; X = attr(_:Attr, _, _)
; X = _:Attr
; X = attrname(attr(Attr, _, _))
; X = attr(Attr, _, _)
; X = Attr
),
atomic(Attr),
atom_concat('xxxID', Rel, Attr),
databaseName(DB),
( storedSpell(DB, DCRel, Rel) ; storedSpell(DB, DCRel, lc(Rel)) ),
relation(DCRel,_), !.
attrlistRemove(attrname(attr(Attr, _, _)),
sizeTerm(CoreR, InFlobR, ExtFlobR)) :-
storedExtendAttrSize(attrname(attr(Attr, _, _)),
sizeTerm(Core, InFlob, ExtFlob)),
CoreR is -1 * Core,
InFlobR is -1 * InFlob,
ExtFlobR is -1 * ExtFlob, !.
attrlistRemove(attrname(attr(Var:Attr, _, _)),
sizeTerm(CoreR, InFlobR, ExtFlobR)) :-
argument( _, rel(Rel, Var)),
downcase_atom(Attr, DCAttr),
downcase_atom(Rel, DCRel),
attrSize(DCRel:DCAttr, sizeTerm(Core, InFlob, ExtFlob)),
CoreR is -1 * Core,
InFlobR is -1 * InFlob,
ExtFlobR is -1 * ExtFlob, !.
% sizeKlass(AttrSize, SizeExt, Size). % Omitted here.
attrlistRemove(attrname(attr(Attr, _, _)), AttrSize) :-
% queryRel(_, rel(Rel, _)),
argument( _, rel(Rel, _)),
downcase_atom(Attr, DCAttr),
downcase_atom(Rel, DCRel),
attrSize(DCRel:DCAttr, AttrSize), !.
% sizeKlass(AttrSize, SizeExt, Size). % omitted here.
attrlistRemove(X, Y) :-
throw(error_Internal(nawra_attrlistRemove(X, Y)::unspecifiedError)),
fail, !.
/*
Calculation of Attribute/Projection List Sizes Terms
The following Rules calculate the combined tuple sizes for a list of attributes,
e.g. to use when applying a ~project~ operator.
---- attrlistSize(+AttrList, sizeTerm(-CoreSize, -InFlobSize, -ExtFlobSize))
----
Returns a term ~sizeTerm(CoreSize, InFlobSize, ExtFlobSize)~ with the
accumulated tuplesize fractions for all attributes found in ~AttrList~.
The predicate can cope with list elements of different types:
~attrname(attr/3)~-terms, ~attr/3~-terms, and plain ~attribute names~
resp. ~var:attr-name~.
PRECONDITION: Can only be called during a query, when the query has been looked up!
*/
attrlistSize([], sizeTerm(0, 0, 0)) :- !.
attrlistSize([X|Xs], SizeTerm) :-
attrlistSize2(X, SizeTerm1),
attrlistSize(Xs, SizeTerm2),
addSizeTerms([SizeTerm1, SizeTerm2], SizeTerm), !.
attrlistSize(X, Y) :-
throw(error_Internal(nawra_attrlistSize(X, Y)::unspecifiedError)),
fail, !.
attrlistSize2(X, AttrSize) :-
( X = attrname(attr(Var:Attr, _, _))
; X = attr(Var:Attr, _, _)
; X = Var:Attr
),
atomic(Attr), atomic(Var),
argument( _, rel(Rel, Var)),
downcase_atom(Attr, DCAttr),
downcase_atom(Rel, DCRel),
relation(DCRel,RelAttrList),
member(DCAttr,RelAttrList),
attrSize(DCRel:DCAttr, AttrSize), !.
% sizeKlass(AttrSize, TupleSizeExt, TupleSize). % Omitted here
% special case: TupleIDs in _small relations
attrlistSize2(X, sizeTerm(12, 0, 0)) :-
( X = attrname(attr(_:Attr, _, _))
; X = attr(_:Attr, _, _)
; X = _:Attr
; X = attrname(attr(Attr, _, _))
; X = attr(Attr, _, _)
; X = Attr
),
atomic(Attr),
atom_concat('xxxID', Rel, Attr),
databaseName(DB),
( storedSpell(DB, DCRel, Rel) ; storedSpell(DB, DCRel, lc(Rel)) ),
relation(DCRel, _), !.
attrlistSize2(X, AttrSize) :-
( X = attrname(attr(Attr, _, _))
; X = attr(Attr, _, _)
; X = Attr
),
atomic(Attr),
% queryRel(_, rel(Rel, _)),
argument( _, rel(Rel, _)),
downcase_atom(Attr, DCAttr),
downcase_atom(Rel, DCRel),
relation(DCRel,RelAttrList),
member(DCAttr,RelAttrList),
attrSize(DCRel:DCAttr, AttrSize), !.
% sizeKlass(AttrSize, TupleSizeExt, TupleSize). % Omitted here
/*
---- simpleTerm(+Term, -STerm, -Size)
----
Simplify a ~Term~ representing extension mapping function, return the simplified
term ~STerm~, and the corresponding sizeTerm ~Size~ (containing the componentwise maxima).
*/
simpleTerm(attr(Var:Attr, _, _), Rel:Attr, AttrSize) :-
argument(_, rel(Rel, Var)),
downcase_atom(Rel, DCRel),
downcase_atom(Attr, DCAttr),
attrSize(DCRel:DCAttr, AttrSize), !.
simpleTerm(attr(Attr, _, _), Rel:Attr, AttrSize) :-
argument(_, rel(Rel, _)),
downcase_atom(Rel, DCRel),
downcase_atom(Attr, DCAttr),
attrSize(DCRel:DCAttr, AttrSize), !.
simpleTerm(Term, STerm, Size) :-
compound(Term),
functor(Term, T, 1), !,
arg(1, Term, Arg1),
simpleTerm(Arg1, SArg1, Size),
functor(STerm, T, 1),
arg(1, STerm, SArg1), !.
simpleTerm(Term, STerm, sizeTerm(Core, InFlob, ExtFlob)) :-
compound(Term),
functor(Term, T, 2), !,
arg(1, Term, Arg1),
arg(2, Term, Arg2),
simpleTerm(Arg1, SArg1, sizeTerm(Core1, InFlob1, ExtFlob1)),
simpleTerm(Arg2, SArg2, sizeTerm(Core2, InFlob2, ExtFlob2)),
Core is max(Core1, Core2),
InFlob is max(InFlob1, InFlob2),
ExtFlob is max(ExtFlob1, ExtFlob2),
functor(STerm, T, 2),
arg(1, STerm, SArg1),
arg(2, STerm, SArg2), !.
simpleTerm(Term, Term, 0) :- !.
/*
Calculate the cost of an extend operator only once. Store the result a a dynamic
fact and reuse the information.
*/
extendSTermCost(STerm, Cost) :- storedExtendSTermCost(STerm, Cost), !.
extendSTermCost(STerm, Cost) :-
predCost(STerm, Cost),
setExtendSTermCost(STerm, Cost), !.
setExtendSTermCost(STerm, _) :- storedExtendSTermCost(STerm, _), !.
setExtendSTermCost(STerm, Cost) :-
assert(storedExtendSTermCost(STerm, Cost)), !.
/*
List with operators which not listing in the POG, are contained in the plan.
The tuple size of the result and the tuple size without Flobs of the result are
shown on the display.
*/
costnewPlan(_, 0) :-
write('There isn\'t a POG. Costs aren\'t calculated '), nl, !.
costnewPlan(Plan, _) :-
write('Operators without POG :'),
highNode(HighNode),
endcostnew(Plan, HighNode, _, TupleSize),
nl, write('The tuple size of the result (tuplesize) is: '),
write(TupleSize), nl, !.
/*
Estimate costs for the non-conjunctive part of the query.
*/
/*
Estimate costs for operator consume.
*/
endcostnew(consume(X), HighNode, Size, TupleSize) :-
endcostnew(X, HighNode, SizeX, TupleSizeX),
TupleSizeX = sizeTerm(Core, InFlob, ExtFlob),
TotalResultTupleSize is Core + InFlob + ExtFlob,
storedOperatorTF(consume, A, B),
Cost is (A * TotalResultTupleSize + B) * SizeX,
costtotal(Cost, CostTotal),
wCostFactor(W),
Cs is CostTotal / W,
write(' consume(Cost: '),
write(Cs), write(' sec.),'),
Size is SizeX,
TupleSize = TupleSizeX,
!.
/*
Determine costs for operator project.
*/
endcostnew(project(X, Arg), HighNode, Size, TupleSize) :-
write(' project,'),
endcostnew(X, HighNode, SizeX, _, _),
attrlistSize(Arg, ArgTupleSize),
TupleSize = ArgTupleSize,
Size is SizeX,
!.
/*
Determine costs for operator count.
*/
endcostnew(count(X), HighNode, Size, TupleSize) :-
write(' count,'),
endcostnew(X, HighNode, SizeX, TupleSizeX),
TupleSize = TupleSizeX,
Size is SizeX,
!.
/*
Determine costs for operator sortby.
*/
endcostnew(sortby(X, _), HighNode, Size, TupleSize) :-
write(' sortby,'),
endcostnew(X, HighNode, SizeX, TupleSizeX),
TupleSize = TupleSizeX,
Size is SizeX,
!.
/*
Determine costs for operator groupby.
*/
endcostnew(groupby( X, _, _), HighNode, Size, TupleSize) :-
write(' groupby,'),
endcostnew(X, HighNode, SizeX, TupleSizeX),
TupleSize = TupleSizeX,
Size is SizeX,
!.
endcostnew(_, HighNode, Size, TupleSize) :-
write(' (Costs'),
resultSize(HighNode, Size),
nodeTupleSize(HighNode, TupleSize),
write(' aren`t calculated),'), !.
endcostnew( _, _, 0, 0) :-
nl,
write('Error at the determination of the operators without POG.'),
nl.
/*
End of file ~nawra.pl~
*/