Query processor for parallel processing in homogenous and heterogenous databases5590319Abstract A query processor for parallel processing translates an input query which references data stored in one or more homogenous or heterogenous databases into a plurality of parallel output queries each of which is directed to a single one of the databases or a partition thereof. A runner combines the results of each of the output queries and integrates them into a single coherent answer set. Claims What is claimed is: Description BACKGROUND OF THE INVENTION
______________________________________
Node Description Comment
______________________________________
SELOP:NOOP SELECT Node (the root)
SCOLSOP:NOOP Column list Node
QNAMEOP:NOOP 1st Column Reference
IDENT:KEYCOLS an SQL identifier
QNAMEOP:NOOP 2nd Column Reference
IDENT:KEYNAME an SQL identifier
FROMOP:NOOP FROM Clause Node
QNAMEOP:NOOP 1st Table Ref.
IDENT:SYSTEM Table Qualifier
IDENT:SYSKEYS Table Name
emptynode
WHEREOP:NOOP WHERE Clause Node
EQLOP:NOOP "=" Comparison
QNAMEOP:NOOP Left Operand Node
IDENT:KEYNAME Name of Operand
STRNG:`FRED; Right Operand Node
ORDEROP:NOOP ORDER Clause Node
QNAMEOP:NOOP 1st Column Ref.
IDENT:KEYCOLS Column Name
______________________________________
The translator 3 also obtains from the MASPAR 15 information about the structure of the database file containing the information that is being referenced, i.e., SYSTEM.SYSKEYS, and constructs a J-tree representation of this file which is stored as a single segment file having 11 fields as follows.
______________________________________
Node Description Comment
______________________________________
EN.sub.-- USERID:SYSTEM
Table name
EN.sub.-- SEGMENT:SQLOUT
Segment within table
EN.sub.-- FIELD:TNAME
Field (1) within segment
EN.sub.-- ALIAS:E01 Alias for field (1)
EN.sub.-- FIELD:TCREATOR
Field (2)
EN.sub.-- ALIAS:E02 Alias (2)
EN.sub.-- FIELD:KEYTYPE
Field (3)
EN.sub.-- ALIAS:E03 Alias (3)
EN.sub.-- FIELD:KEYNAME
Field (4)
EN.sub.-- ALIAS:E04 Alias (4)
EN.sub.-- FIELD:KEYCOLS
Field (5)
EN.sub.-- ALIAS:E05 Alias (5)
EN.sub.-- FIELD:INAME
Field (6)
EN.sub.-- ALIAS:E06 Alias (6)
EN.sub.-- FIELD:REFTNAME
Field (7)
EN.sub.-- ALIAS:E07 Alias (7)
EN.sub.-- FIELD:REFTCREATOR
Field (8)
EN.sub.-- ALIAS:E08 Alias (8)
EN.sub.-- FIELD:DELETERULE
Field (9)
EN.sub.-- ALIAS:E09 Alias (9)
EN.sub.-- FIELD:STATUS
Field (10)
EN.sub.-- ALIAS:E10 Alias (10)
EN.sub.-- FIELD:TIMESTAMP
Field (11)
EN.sub.-- ALIAS:E11 Alias (11)
______________________________________
At this point, the translator 3 consults its meta-data files and finds that SYSTEM.SYSKEYS is partitioned into SYSTEM.SYSKEYS1 and SYSTEM.SYSKEYS2. Each partition has an associated set membership condition. The system generates an SQL query corresponding to the first such condition as follows. SELECT X FROM Y WHERE (KEYNAME>=`MM`) AND ((KEYNAME<>`MM`) OR (KYCOLS>=3)) The query may be expressed in terms of dummy column and table names, "X" and "Y", because only the WHERE clause is of consequence. A parser, more fully described below, reduces the query to the following tree structure.
______________________________________
Node Description Comment
______________________________________
SELECT SELOP The root node
SCOLSOP Dummy SELECT list
QNAMEOP
QNAMEPART IDENT X
FROMOP Dummy FROM clause
QNAMEOP
QNAMEPART IDENT Y
EMPTYNODE
WHEREOP The split condition
ANDOP AND
GEQOP >=
QNAMEOP left operand of >=
QNAMEPART IDENT KEYNAME
LITSTRING STRNG `MM` right operand of >=
OROP OR
NE NEQOP <>, left opr of OR
QNAMEOP left operand of <>
QNAMEPART IDENT KEYNAME
LITSTRING STRNG `MM`
GEQOP >=, right opr of OR
QNAMEOP left opr of >=
QNMAEPART IDENT KEYCOLS
LITINT FIXED 3 right opr of >=
______________________________________
The forgoing specifies the condition predicate for the first partition, SYSTEM.SYSKEYS1 of the database SYSTEM.SYSKEYS. The "WHEREOP" subtree of this tree is then merged ("ANDed") with the tree representing the input query. This results in a new tree containing the following "WHEREOP" subtree.
______________________________________
Node Description Comment
______________________________________
WHEREOP:NOOP Root of sub-tree
ANDOP:NOOP AND (a)
ANDOP:NOOP AND (b)
GEQOP:NOOP >=
QNAMEOP:NOOP left opr of >=
IDENT:KEYNAME operand name
STRNG:`MM` right opr of >=
OROP:NOOP OR (a)
OROP:NOOP OR (b), left opr of (a)
LESSOP:NOOP <, left opr of (b)
QNAMEOP:NOOP left opr of <
IDENT:KEYNAME Operand name
STRNG:`MM` right opr of <
GRTROP:NOOP >, right opr of (b)
QNAMEOP:NOOP left opr of >
IDENT:KEYNAME Operand name
STRNG:`MM` right opr of >
GEQOP:NOOP >=, right opr of (a)
QNAMEOP:NOOP left opr of >=
IDENT:KEYCOLS Operand name
FIXED:3 right opr of >=
EQLOP:NOOP =, right opr of a
QNAMEOP:NOOP left opr of =
IDENT:KEYNAME Operand name
STRNG:`FRED` right opr of =
______________________________________
The foregoing tree will not contribute to the end result due to an incompatibility between the conditions KEYNAME>=`MM` and KEYNAME=FRED. Hence, this particular split query is slated to be removed from consideration, i.e., pruned from the tree, since it can not contribute to the answer to the input query. The translator now examines the set membership condition, i.e., condition predicate, for the second partition, SYSTEM.SYSKEYS2, which is stated in SQL as:
______________________________________
SELECT X FROM Y WHERE
(KEYNAME <= `MM`)
AND
((KEYNAME <>`MM`) OR (KEYCOLS <3));
______________________________________
The translator 3 parses the foregoing query to produce another "WHEREOP" subtree and merges (ANDs) it with the sub-tree of the input query to obtain the following tree.
______________________________________
Node Description Comment
______________________________________
SELOP:NOOP The root
SCOLSOP:NOOP Column list node
QNAMEOP:NOOP 1st column reference
IDENT:KEYCOLS Column name
QNAMEOP:NOOP 2nd column reference
IDENT:KEYNAME Column name
FROMOP:NOOP FROM clause node
QNAMEOP:NOOP 1st table reference
IDENT:SYSTEM Qualifier
IDENT:SYSKEYS2 Table name (2nd part)
emptynode
WHEREOP:NOOP WHERE clause node
ANDOP:NOOP AND (a)
ANDOP:NOOP AND (b)
LEQOP:NOOP <=, left of opr of b
QNAMEOP:NOOP left opr of <=
IDENT:KEYNAME name of operand
STRNG:`MM right opr of <=
OROP:NOOP OR
NEQOP:NOOP <>, left opr of OR
QNAMEOP:NOOP left opr of <>
IDENT:KEYNAME operand name
STRNG:`MM` right opr of <>
LESSOP:NOOP <, right opr of OR
QNAMEOP:NOOP left opr of <
IDENT:KEYCOLS name of operand
FIXED:3 right opr of <
EQLOP:NOOP =, right opr of a
QNAMEOP:NOOP left opr of =
IDENT:KEYNAME name of operand
STRNG:`FRED` right opr of =
______________________________________
This tree contributes to the end result. The translator 3 then prunes the tree and transforms the resulting WHERE clause to obtain the following WHERE clause sub-tree.
______________________________________
Node Description Comment
______________________________________
WHEREOP:NOOP WHERE clause node
ANDOP:NOOP AND (a)
ANDOP:NOOP AND (b)
LEQOP:NOOP <=, left opr of b
QNAMEOP:NOOP left opr of <=
IDENT:KEYNAME name of operand
STRNG:`MM` right opr of <=
OROP:NOOP OR (c), right opr of b
OROP:NOOP OR (d), left opr of c
LESSOP:NOOP <, left opr of d
QNAMEOP:NOOP left opr of <
IDENT:KEYNAME operand name
STRNG:`MM` right opr of <
GRTROP:NOOP >, right opr of d
QNAMEOP:NOOP left opr of >
IDENT:KEYNAME operand name
STRNG:`MM` right opr of >
LESSOP:NOOP right opr of c
QNAMEOP:NOOP left opr of <
IDENT:KEYCOLS operand name
FIXED:3 right opr of <
EQLOP:NOOP =, right opr of a
QNAMEOP:NOOP left opr of =
IDENT:KEYNAME operand name
STRNG:`FRED` right opr of =
______________________________________
From the above tree, the translator 3 produces the following SQL query.
______________________________________
SELECT KEYCOLS ,KEYNAME
FROM SYSTEM.SYSKEYS
WHERE
(KEYNAME <=`MM`) AND
((KEYNAME <>`MM`) OR (KEYCOLS <3))
AND
(KEYNAME = `FRED`)
______________________________________
This SQL output query is applied to SYSTEM.SYSKEYS2, the second partition. The system wastes no time searching SYSTEM.SYSKEYS1. The query processor 1 of the invention will now be described in greater detail with particular reference to FIG. 2. The translator 3 comprises a lexical analyzer 5, a parser 7, a semantic analyzer 11, a normalizer 13, a planner 17, a splitter 19 and a code generator 21. As will be known to those skilled in the art, each of these components may be realized on a computer processor having associated random access memory. A server computer may be configured to perform the functions of these components, to receive a query from a client computer 69, process it in accordance with the invention and return the answer set specified by the query to the client computer 69. The lexical analyzer 5 transforms digital signals representing the text of an SQL query to digital signals representing a sequence of SQL tokens and passes them, on request, to the parser 7. There are many kinds of SQL tokens: character string literals, delimited identifiers, special characters, relational operators, numeric literals, national character strings, identifiers and key words. The lexical analyzer 5 extracts the next word or other significant symbol of the SQL language from the source query string when it receives a signal from the parser and delivers signals representing the aforementioned word or symbol to the parser 7. The parser 7, having received and analyzed the tokens comprising the source query, constructs an abstract syntax tree (AST) depicting the source query and directs signals representing that AST to the semantic analyzer 11 for further processing. The semantic analyzer 11 scans the AST and constructs from the information contained therein another representation of the source query hereinafter referred to as a "J-tree." The J-tree encapsulates the latent information contained in the source query in a form suitable for manipulation in a computer memory. The semantic analyzer 11 determines whether the source query is consistent with the database schema encoded in the meta-data database 70 before it permits the translation process to continue. It rejects all queries that do not conform to the semantic rules of SQL. Query validation requires the services of MASPAR 15 which, upon receipt of the appropriate signals, assembles signals representing the database objects referenced in the J-tree. MASPAR 15 contains circuitry for comparing the table and column names found in the J-tree with table and column names found in the meta-data database. For each table or column reference signal it receives, MASPAR 15 returns either a "not found" signal or a signal representing the internal structure of the database object corresponding to the table or column name. The semantic analyzer 11 uses the signals generated by MASPAR 15 in this context both to validate the query and to augment selected nodes of the J-tree with additional information. Having accepted the source query, the semantic analyzer 11 passes a signal to the normalizer 13, which ensures that the query represented by the J-tree at that moment has been expressed soley in terms of base tables. SQL queries may reference two kinds of tables: base tables, the contents of which are actually recorded on external digital storage media, and views, which have no direct physical representation. A view, in SQL terminology, is an object defined in terms of any number of other base tables and views that retains the important characteristics of a base table. Since the planner 17, splitter 19 and code generator 21 require information about base table partitions, view references must be systematically replaced by equivalent base table references before the planner 17, splitter 19 and code generator 21 can perform their respective functions. The operation of the normalizer is illustrated in FIG. 3 with the assumption that a J-tree, T0, exists and that the FROM list of T0 contains a set, v, of view references. The procedure first invokes itself recursively to process nested SELECT sub-trees of T0. Having normalized all such nested SELECTS, the procedure considers every remaining view reference x in v, replacing each with one or more table references. This step entails recursively normalizing the view definition, dx, of x and merging T0 and dx. The merge step, shown as a single box in FIG. 3 involves substituting the view column references with corresponding table column references taken from dx, replacing the view reference, x, with the entire FROM sub-tree of dx and ANDing the WHERE sub-tree of dx with that of T0. Should dx contain contain a GROUP BY subtree, the normalizer 13 ANDs the corresponding HAVING sub-tree with the WHERE sub-tree of dx. To avoid introducing ambiguous references, the normalizer 13 replaces all column references in T0 and dx with uniquely qualified column references. Should this process generate an operation that can not be performed, the normalizer 13 rejects the query rather than continuing. The normalization process is illustrated by the following example. Intermediate results, which are shown here in flattened text form for readability, should be understood to describe J-trees. View Definitions: CREATE VIEW SALES (PNAME, PCODE, PDESCR, PCOST, VOL, REGION, MONTH) AS SELECT P.PNAME, S.PCD, P.PDESCR, P.PCOST, S.VOL, S.REG, S.MON FROM SALES.sub.-- BASE S, PROD.sub.-- BASE P WHERE S.PCD=P.PCD; CREATE VIEW HIGHLIGHTS AS SELECT PNAME, PCODE, VOL, REGION, MONTH FROM SALES WHERE VOLUME>(SELECT AVG(VOL) FROM SALES WHERE MONTH=`DEC`); CREATE VIEW OUR.sub.-- SALES (PRODUCT.sub.-- NAME, PRODUCT.sub.-- CODE, VOLUME) AS SELECT * FROM HIGHLIGHTS WHERE REGION IN (`Hither`, `Yon`); Sample Query (T0): SELECT, FROM OUR.sub.-- SALES WHERE PRODUCT.sub.-- NAME LIKE `%cycle`; The Normalization of T0 takes place as follows. The normalizer 13 retrieves the "CREATE VIEW OUR.sub.-- SALES . . ." statement, reduces the statement to a J-tree, T1, and normalizes the tree by calling itself recursively. Initially, T1, takes the following form: SELECT * FROM HIGHLIGHTS WHERE REGION IN (`Hither`, `Yon`); In the process of normalizing T1 the system must access another view definition, T2. Initially, T2 takes the following form: SELECT PNAME, PCODE, VOL, REGION, MONTH FROM SALES WHERE VOLUME> (SELECT AVG(VOL) FROM SALES WHERE MONTH=`DEC`); T2 contains a sub-query, T3, that must be normalized. But T3 is also cast in terms of a view. The normalizer 13 accesses the SALES view definition and converts it into yet another J-tree, T4. Initially, T4 takes the following form: SELECT P.PNAME, S.PCD, P.PDESCR, P.PCOST, S.VOL, S.REG, S.MON FROM SALES.sub.-- BASE S, PROD.sub.-- BASE P WHERE S.PCD=P.PCD Since T4 is in normal form, it can be merged with T3 to produce a new version of T3: SELECT AVG(S.VOL) FROM SALES.sub.-- BASE S, PROD.sub.-- BASE P WHERE (S. PCD=P. PCD ) AND (S. MONTH=`DEC`); T2, once it has been normalized, has the following appearance: SELECT PNAME, PCODE, VOL, REGION, MONTH FROM SALES WHERE VOLUME> (SELECT AVG(VOL) FROM SALES.sub.-- BASE S1, PROD.sub.-- BASE P1 WHERE (S1.PCD=P1.PCD) AND (MONTH=`DEC`)); But T2 still contains a reference to the SALES view, T4. Merging and T2 and T4 produces another T2 revision: SELECT P2.PNAME, S2.PCD, S2.VOL, S2.REG, S2.MON FROM SALES.sub.-- BASE S2, PROD.sub.-- BASE P2 WHERE (S2.PCD=P2.PCD) AND (S2.VOLUME>(SELECT AVG(VOL) FROM SALES.sub.-- BASE S1, PROD.sub.-- BASE P1 WHERE (S1.PCD=P1.PCD) AND (MONTH=`DEC`)); Merging this with T1 yields T1 in its final form: SELECT P2.PNAME, S2.PCD, S2.VOL, S2.REG, S2.MON FROM SALES.sub.-- BASE S2, PROD.sub.-- BASE P2 WHERE (S2. PCD=P2. PCD) AND (S2.VOLUME> (SELECT AVG(S1.VOL) FROM SALES.sub.-- BASE S1, PROD.sub.-- BASE P1 WHERE (S1.PCD=P1.PCD) AND (MONTH=`DEC`)) AND (S2.REGION IN (`Hither`, `Yon`)); When it has completed its work, the normalizer 13 signals the splitter which partitions the source query into independently executable units. The splitter bases its decisions on meta-data descriptions which, by this time, have been brought into memory and stored in a variant of J-tree used to retain such information. If the source query addresses only monolithic tables or is thought to be optimal as it stands, the system makes no attempt to split it. The splitter 19 breaks divisible queries into tasks that can take place in parallel. A normalized J-tree is considered to be a candidate for decomposition if (1) any base table, T, referenced in its FROM subtree is the union of multiple, disjoint, SQL union-compatible base tables, (2) any base table referenced in its FROM sub-tree has been partitioned into disjoint subsets on the basis of key field ranges or (3) its root node contains a union operator. The system processes SQL UNION statements in parallel even if the individual queries that comprise the union cannot be decomposed. FIGS. 4a, 4b, and 4c depict the overall logic of the splitter, which begins by determining whether J-tree Q (FIG. 4a) represents a UNION operation. If it does, the splitter invokes itself recursively to partition both branches of the tree. Note that if additional UNION operations were embedded in either branch of the tree, the splitter would detect them and, once again, invoke itself recursively to partition each branch. Since UNION operations must, by definition, occur at a higher level than SELECT operations, this strategy effectively removes UNIONS from consideration before the SELECT node is detected. Having dispensed with UNIONs, the splitter 19 scans for subqueries, constructs which may have been employed to specify individual values or columns of values in the predicate. SQL defines two kinds of sub-queries: correlated and uncorrelated. Correlated sub-queries require special handling because they cannot be evaluated independently of the query in which they are embedded. The splitter attempts to replace every uncorrelated subquery with a value or column of values before continuing. This entails (1) detecting an uncorrelated sub-query, Qs, (2) splitting Qs, (3) executing Qs and (4) recasting the Qs sub-tree in terms of literal values. Thus, the subtree representing "A=(SELECT AVG(Age) FROM Personnel" might be replaced by the equivalent of "A=37" and the subtree representing "X IN (SELECT ModelNumber FROM Products WHERE Qty.sub.-- On.sub.-- Hand<100)" might be replaced by the equivalent of "X IN (100, 221, 085)". IN lists, because their size can not be known apriori, present a special problem. If the number of elements exceeds a DBMS-dependent threshold, the splitter must store them in a temporary table, Tmp, for example, and replace the predicate in question with the equivalent of `X IN (SELECT * FROM Tmp)". A false predicate, as referred to in FIG. 4a, is an SQL predicate containing an inexpensive sub-query that is guaranteed to produce a suitable result. For example "1=SELECT 2 FROM EMPTYTABLE". Once all uncorrelated sub-queries have been replaced, the splitter examines the FROM list of the J-tree. FROM lists, at this stage in the process, can contain an unspecified number of table references (view references have already been replaced by the normalizer 13). References to "concatenated" tables, the components of which are seen as separately addressable tables by participating DBMSs, and "partitioned" tables, which are not, must be treated differently. A query containing a concatenated table reference, T, always gives rise to one task for every component of T while a query containing a partitioned table reference need not be split at all. Thus, FIG. 4 shows Q being split relative to its concatenated table reference before invoking the DBMS-dependent "Explain" function (FIG. 4b). The Explain function, which may not necessarily be available, is a generic name for a facility that examines a proposed query and returns information about how a particular DBMS would process it. The system uses such information to determine (1) whether to split and (2) what partitioned table or tables in the FROM list can best be used as the basis for splitting. Query optimization at this level is highly DBMS-dependent and can only be brought into play when partitioned tables are addressed. The logic illustrated in FIG. 4b is capable of splitting a query Q relative to every partitioned table it references. In practice, splitting is constrained by DBMS-dependent rules. Finally, the splitter 19 looks for correlated sub-queries referencing concatenated tables. Such queries can not be processed as stated by the SQL DBMS engines because the engines are unaware of concatenated table names. Concatenated tables, which are logical entities, are defined as the union of one or more base tables. A DBMS can address the component parts of a concatenated table but not, as is required in the case of correlated sub-queries, the table as a whole. To solve the addressability problem the system must materialize the information required to satisfy the correlated sub-query and store it in a temporary table local to a selected DBMS. It attempts to do so by generating a suitably qualified SQL UNION request. It is crucial that the UNION operation produce answer sets of a manageable size. The system requests only those rows and columns that are required to evaluate the predicate under consideration. It derives the column list by enumerating column references in the correlated sub-query and forms a predicate by copying relevant conditions from its WHERE clause. Normally it is possible to guarantee a priori that the answer set produced in this fashion will be far smaller than a straightforward materialization of the concatenated table in question. But if this is not the case, and the projected size of the intermediate result exceeds a user-defined threshold value, the splitter 19 aborts the source query and returns a diagnostic message to the client. The correlated sub-query strategy for concatenated tables is illustrated by the following example. Consider the following query: SELECT EName FROM emp e1 WHERE Salary> (SELECT AVG(Salary) FROM emp e2 WHERE e1. Dpt=e2.Dpt); If emp were partitioned on Dpt N, queries of the following form could be generated. This is possible because e1.Dpt is known to be the same as e2.Dpt. Since Dpt is the partitioning key, the sub-query need can be evaluated without crossing subset boundaries. SELECT EName FROM emp e1[i] WHERE Pred(e1[i]) AND Salary> (SELECT AVG(Salary) FROM emp e2[i] WHERE e1.Dpt=e2.Dpt AND pred(e2[i])); But if emp is not partitioned on Dpt (i.e., the sub-query spans subset boundaries) the inner query can not be split. An intermediate table, T, defined as follows, must be introduced. T(Dpt, Number, Amount) Having created T, the query processor 1 then populates it with N result sets.
______________________________________
INSERT INTO T
SELECT Dpt, SUM(VALUE(LENGTH(EName), 1)*0+1),
SUM(Salary)
FROM emp[1]
GROUP BY Dpt
HAVING COUNT(*) > 0;
INSERT INTO T
SELECT Dpt, SUM(VALUE(LENGTH(EName), 1)*0+1),
SUM(Salary)
FROM emp[2]
GROUP BY Dpt
HAVING COUNT(*) > 0;
. . .
INSERT INTO T
SELECT Dpt, SUM(VALUE(LENGTH(EName), 1)*0+1),
SUM(Salary)
FROM emp[N]
GROUP BY Dpt
HAVING COUNT(*) > 0;
______________________________________
Once T is fully populated, the query processor issues N correlated queries of the form: SELECT EName FROM emp [i] WHERE emp. Salary> (SELECT SUM(T.Amount) / SUM(T.Number) FROM T WHERE emp. Dpt=T.Dpt); Finally, the result sets are merged and T is dropped. A split query must be issued for every component of a concatenated table reference. When the client calls for concatenated tables, T1, T2, . . . , Tn to be joined, for example, the query generator 1 is forced to generate a split query for every permutation and combination of the components of T1, T2, . . . , Tn. In consequence, the method depicted in FIGS. 4a, b, c is capable of deriving every possible split query from a given source request. The query generator can actually optimize performance by splitting the source request selectively. Selective splitting is possible for tables partitioned on split key ranges. For such tables, the splitter 19 identifies which queries are worth submitting for parallel execution by examining a set of DBMS-specific rules designed to optimize the overall performance of the system. The following rules have been developed specifically for the IBM DB/2 DBMS engine. In the case of DB/2, the splitter 19 recognizes six general classes of SQL query (called Q below) for the purpose of split range key table parallelization: (1) A UNION [ALL] query: Break n-way Union operations into n separate subordinate query specifications and split each of them individually. (2) A simple ungrouped query (Q) with one table reference (T) in the FROM list, no HAVING clause and no correlated sub-queries: Providing T is composite, and the EXPLAIN data provides ample justification to proceed, split Q on the partitioning key of T as shown in the previous example. (3) A simple grouped query whose GROUP BY specification is the partitioning key (or an ungrouped query with a HAVING clause): If T is composite, split Q relative to T. (4) A 2-way join(T1 X T2): If T1 and T2 are partitioned m and n ways, respectively, the splitter 19 is capable of generating as many as m*n tasks. Do not attempt a two-way split unless DB/2 Explain data shows it to be advantageous. "Star" joins, in which all the join columns are partitioning keys (with identical range or subsetted boundaries), may be split into one replica per partition. For other queries, do an EXPLAIN on the source query and split on the partitioning key of the outer table, T1, of the join. If T2 happens to be partitioned on the same columns as T1 generate a 2-way split. (5) An n-way join (T1.times.T2 . . . X Tj): The strategy for n-way joins is a generalization of the 2-way join strategy. In the concatenated case as many as n1, n2 . . ,nj queries could result. In the split key case, partition on the outermost table of the DB/2-selected join order and then expand to two-way partitioning in the event of a star join. Attempt to expand to three-way partitioning in the case of a second star join. (6) A query, Q, with a correlated sub-query, SQ: do not split SQ unless it addresses a concatenated table. Limit splitting to the parent query. When it completes its work the splitter 19 passes two signals, the address of the root node (r) of the J-tree and the address (d) of a descriptor list indicating how to produce many statements from r. The purpose of the code generator 21 is to generate signals representing the text of the SQL statements encoded by r and d. To produce text, the code generator 21 traverses r in a top-to-bottom, left-to-right fashion, emitting the text of one or more tokens for every node it visits. For J-tree nodes representing column names in the select list, for example, the code generator 21 copies the identifier, suitably delimited, to its result string. Other nodes representing higher level constructs such as sub-selects and expressions require special treatment. Sub-selects, for example, might give rise to a leading "(" followed by the result of flattening the sub-select, followed by a closing")". The code generator 21 suppresses HAVING clauses that have been marked as post-processing steps by the splitter 19. Assume a tree, T, representing the following grouped query is submitted to the code generator 21. SELECT DEP.sub.-- NBR, SUM(SALES) FROM SALES.sub.-- INFO WHERE REGION=`East` GROUP BY DEP.sub.-- NBR HAVING AVG (SALES)>100000, From this, the code generator 21 might produce the following text: SELECT DEP.sub.-- NBR, SUM(SALES), SUM(VALUE(LENGTH(COST),0+1,0)) FROM SALES.sub.-- INFO GROUP BY DEP.sub.-- NBR; Eventually, when the runner 67 receives intermediate answer sets, it merges the data, computes the aggregate functions, applies the suppressed HAVING clause and builds an answer set. The runner 67 controls parallel query execution. It submits tasks to selected DBMSs, processes the result sets returned by participating DBMSs and produces answer sets satisfying the source query. Like other components of the query processor 1 the runner 67 is driven by information organized in the form of a J-tree (T). Initially, the runner 67 traverses T, submitting a request for every query specification encoded by T. It issues SQL requests to selected DBMSs and awaits results. When the first row of an answer set arrives, it starts processing data. What it does then depends on T. For an unsplit straightforward end-user request, the runner 67 relays output rows more or less unchanged to the client; for an unordered UNION ALL the runner 67 merges answer sets; for an ordered UNION, it is obliged to remove duplicates as it merges; for a query with a HAVING clause, it may apply SQL aggregate functions to column values; for a distributed join, it combines rows that satisfy a specified join condition; and finally, for an uncorrelated sub-query, the runner 67 writes a result (a value or file reference) into a designated memory location. It is to be appreciated that the foregoing is a description of a preferred embodiment of the invention to which variations and modifications may be made without departing from the spirit and scope of the invention.
|
Same subclass Same class Consider this |
||||||||||
