
24
of tables and columns referenced in the
query and looks them up in the System R cat-
alogs to verify their existence and to
retrieve information about them.
The catalog lookup portion of the OPTI-
MIZER also obtains statistics about the
referenced relations, and the access paths
available on each of them. These will be
used later in access path selection. After
catalog lookup has obtained the datatype
and length of each column, the OPTIMIZER
rescans the SELECT-list and WHERE-tree to
check for semantic errors and type compati-
bility in both expressions and predicate
comparisons.
Finally the OPTIMIZER performs access
path selection. It first determines the
evaluation order among the query blocks in
the statement. Then for each query block,
the relations in the FROM list are pro-
cessed. If there is more than one relation
in a block, permutations of the join order
and of the method of joining are evaluated.
The access paths that minimize total cost
for the block are chosen from a tree of
alternate path choices. This minimum cost
solution is represented by a structural
modification of the parse tree. The result
is an execution plan in the Access Specifi-
cation Language (ASL) <10>.
After a plan is chosen for each query
block and represented in the parse tree, the
CODE GENERATOR is called. The CODE GENERA-
TOR is a table-driven program which trans-
lates ASL trees into machine language code
to execute the plan chosen by the OPTIMIZER.
In doing this it uses a relatively small
number of code templates, one for each type
of join method (including no join). Query
blocks for nested queries are treated as
“subroutines” which return values to the
predicates in which they occur. The CODE
GENERATOR is further described in <9>.
During code generation, the parse tree is
replaced by executable machine code and its
associated data structures. Either control
is immediately transferred to this code or
the code is stored away in the database for
later execution, depending on the origin of
the statement (program or terminal). In
either case, when the code is ultimately
executed, it calls upon the System R inter-
nal storage system (RSS) via the storage
system interface (RSI) to scan each of the
physically stored relations in the query.
These scans are along the access paths cho-
sen by the OPTIMIZER. The RSI commands that
may be used by generated code are described
in the next section.
3. The Research Storage System
The Research Storage System (RSS) is the
storage subsystem of System R. It is respon-
sible for maintaining physical storage of
relations, access paths on these relations,
locking (in a multi-user environment), and
logging and recovery facilities. The RSS
presents a tuple-oriented interface (RSI)
to its users. Although the RSS may be used
independently of System R, we are concerned
here with its use for executing the code
generated by the processing of SQL state-
ments in System R, as described in the pre-
vious section. For a complete description
of the RSS, see <1>.
Relations are stored in the RSS as a col-
lection of tuples whose columns are physi-
cally contiguous. These tuples are stored
on 4K byte pages; no tuple spans a page.
Pages are organized into logical units
called segments. Segments may contain one
or more relations, but no relation may span
a segment. Tuples from two or more relations
may occur on the same page. Each tuple is
tagged with the identification of the rela-
tion to which it belongs.
The primary way of accessing tuples in a
relation is via an RSS scan. A scan returns
a tuple at a time along a given access path.
OPEN, NEXT, and CLOSE are the principal com-
mands on a scan.
Two types of scans are currently avail-
able for SQL statements. The first type is a
segment scan to find all the tuples of a
given relation. A series of NEXTs on a seg-
ment scan simply examines all pages of the
segment which contain tuples, from any
relation, and returns those tuples belong-
ing to the given relation.
The second type of scan is an index scan.
An index may be created by a System R user
on one or more columns of a relation, and a
relation may have any number (including
zero) of indexes on it. These indexes are
stored on separate pages from those con-
taining the relation tuples. Indexes are
implemented as B-trees <3>, whose leaves
are pages containing sets of (key, identi-
fiers of tuples which contain that key).
Therefore a series of NEXTs on an index scan
does a sequential read along the leaf pages
of the index, obtaining the tuple identifi-
ers matching a key, and using them to find
and return the data tuples to the user in
key value order. Index leaf pages are
chained together so that NEXTs need not ref-
erence any upper level pages of the index.
In a segment scan, all the non-empty
pages of a segment will be touched, regard-
less of whether there are any tuples from
the desired relation on them. However, each
page is touched only once. When an entire
relation is examined via an index scan, each
page of the index is touched only once, but
a data page may be examined more than once
if it has two tuples on it which are not
“close” in the index ordering. If the tuples
are inserted into segment pages in the index
ordering, and if this physical proximity
corresponding to index key value is main-
tained, we say that the index is clustered
.
A clustered index has the property that not
only each index page, but also each data
page containing a tuple from that relation
文档被以下合辑收录
相关文档
评论