Professional Documents
Culture Documents
2. Specified record order
3. Enforced uniqueness
Index Costs
1. Index maintenance overhead occurs
during an add or delete of a record or
modification of an index component.
2. Additional disk space
General Indexing Properties
❂ Bracketing affects rapid record retrieval
❂ Sorting affects specified record order
Bracketing
❂ Using an index to read a subset of
records from a table based upon
conditions specified in WHERE, OF and
USING clauses.
Sorting
❂ Reading records in a specified order
may be accomplished by using an
index. However, if it cannot be
accomplished by using an index, then a
sort table is built.
When to Create an Index
1. Unique index
2. Foreign keys
3. Reducing record reads
A. Date fields
B. Logical fields
4. Composite names
5. Description fields
Unique Index
1. Relational database design requires
that there should be at least one index
per table that can uniquely identify each
record in that table.
• Progress doesn’t require an index to be
created, in which case it automatically
creates a default index in dbkey order.
– This index may or may not be chronological,
since dbkeys can be reused.
Foreign Keys
2. Create indexes for all foreign keys of a
table.
• A foreign key is a key in a table that is a
unique key in another table. This key
represents a parent record to an existing
record.
• Indexing foreign keys gives parent records
fast access to all child records.
Foreign Keys
/* Example 1 */
for each student,
each stuchrg of student:
display stuchrg.
end.
❂ 1000 students
❂ 40 charges per student
❂ 40,000 student/charge records
❂ Using index StudentIDChargeDate: 41,000 record reads
❂ Not using index StudentIDChargeDate: 40,001,000 record
reads
Reducing Record Reads
3. Create indexes on fields used for record
selection.
• Since the smaller the bracket the more
efficient the index, you should apply
bracketing concepts.
Bracketing with Date Fields
❂ Index date fields
• Users like to view records for certain time
periods.
– Without an index on chargedate, the search
would have to read every record in the table.
Bracketing with Date Fields
/* Example 2 */
for each stuchrg where charge-date ge 9/1/96
and charge-date le 9/2/96:
display stuchrg.
end.
Bracketing with Logical Fields
❂ Indexing can be effective with logical
fields if the split between the “yes” and
“no” values will not be 5050, often
creating a smaller bracket.
• Avoid using NOT in front of a logical field,
as in Example 4, since Progress won’t
bracket. Use field = NO instead.
Bracketing with Logical Fields
/* Example 3 */
for each student where graduated = no:
display student.
end.
/* Example 4 */
for each student where not graduated:
display student.
end.
Composite Names
4. Consider building composite indexes for
name fields (e.g. lastname +
firstname), since users like to see
records in alphabetical order.
Description Fields
5. Description fields should be word
indexed, so that records can be
accessed using specific keywords.
• Examples:
– Partdescription in an item table
– Ordercomments in an order table
Bracketing with Word Indexes
/* word.p */
def var wordvar as char format "x(30)" label "Words".
repeat:
update wordvar.
for each stuchrg
where student-charge-description contains wordvar:
display stuchrg.
end. /* for each */
end. /* repeat */
No Bracketing with Matches
/* matches.p */
def var wordvar as char format "x(30)"
label "Word Match".
repeat:
update wordvar.
for each stuchrg
where student-charge-description matches wordvar:
display stuchrg.
end. /* for each */
end. /* repeat */
Index Rules Overview
Manual Index Selection
❂ If USEINDEX is used in the
Record Phrase, the requested index is
always used, regardless of its
efficiency.
❂ If a RECID or ROWID is used in the
WHERE clause, the record is always
retrieved using the RECID or ROWID,
unless USEINDEX is used.
Index Rules Overview
❂ Factors Progress considers when
deciding which index(es) to use are:
• Unique indexes
• Equality matches
• Range matches
• Sort matches
• Primary indexes
• Word indexes
Equality Matches
❂ An equality match occurs whenever a
field is equal to (=, EQ) an expression in
an OF, WHERE, or USING clause.
❂ If the expression includes a reference to
any fields in the same record buffer,
then the equality match is not active.
Equality Matches
Record-phrase AEM
offering.offering-id =5 Yes
Record-phrase ARM
offering.dow < 3 Yes
offering.course-id <> 5 No
file:///D:/idxprfrm/PwrPnt/AND Bracketing.BMP
Sort Matches
❂ A sort match is present whenever a field
and not an expression appears in a BY
phrase.
❂ You can have multiple BY phrases;
each counts as one sort match as long
as they are sorted in the same order as
they are in the index.
Sort Matches
BY offering.dow No
BY offering.from-time / 3600 No
Multiple Index Rules
Multiple Index Rules
❂ Since a word index is such a powerful
search mechanism, it is always used if a
CONTAINS is found in the WHERE
clause.
❂ Next, Progress determines whether the
AND or OR connectors are used and
applies the appropriate set of rules, if
any.
Multiple Index Rules –
Word Index
❂ When at least one criteria utilizes a
word index, at least the word index will
be used, and other indexes are used if
Rule 2 and Rule 3 are met.
Multiple Index Rules – AND
❂ More than one index can be used with
AND when:
• All components of each index are involved
in an active equality match.
• None of the indexes involved in the active
equality match are unique.
Multiple Index Rules – AND
❂ When multiple
indexes are used
with an AND, the
final results list is an
intersection of the
results list for each
index.
Multiple Indexes – AND
❂ Why such strict AND rules?
• The shaded area in the diagram is
relatively small, normally reflecting a
relatively small number of records
returned. Therefore, it is usually more
efficient to use a single index, rather than
pull records efficiently from multiple
indexes only to discard them.
Multiple Index Rules – OR
❂ More than one index can be used with
OR when both criteria utilize at least the
leading component of an index. Unlike
AND:
• Only the leading components of any index
must be used.
• Range matches as well as equality
matches may be used.
Multiple Index Rules – OR
❂ When multiple
indexes are used
with an OR, the final
results list is a union
of the results lists of
the indexes, with
duplicates
discarded.
Multiple Index Rules – OR
❂ Why are OR rules not as strict as AND?
• Because OR is a union and not an
intersection, fewer records will tend to be
discarded. Therefore, the efficiency of
reading records based on leading
components has a much greater positive
affect on performance.
Single Index Rules
1. Unique index with fewest components where all
components are used in active equality matches
2. More active equality matches
3. More active range matches
4. All components used in an active equality match
5. More sort matches
6. The primary index
7. The first index alphabetically
Single Index Rules – Rule 1
❂ A unique index with all of its
components used in active equality
matches (AEMs) will be chosen, even if
another index has more active equality
matches, since using all components of
a unique index in AEMs means there’s
a direct hit on a single record.
Single Index Rules – Rules 2 to 7
❂ Rules 1 to 4 are designed to choose the
smallest bracket of records.
❂ After bracketing, Progress looks for the
minimal amount of sorting needed, or
arbitrarily selects the primary index, or
first index alphabetically. (Single Index
Rules 5, 6 and 7)
Counting AEMs and ARMs
❂ When counting AEMs and ARMs (active
range matches), remember to apply
bracketing rules for counting.
• If the comparison is an AEM, then the next
component comparison may be counted
for either an AEM or an ARM.
Counting AEMs and ARMs
❂ When counting AEMs and ARMs (active
range matches), remember to apply
bracketing rules for counting.
• If the comparison is an ARM, then no
subsequent component comparison may
be counted as either an AEM or ARM.
Single Index Rules – Rule 4
❂ Rule 4 tells Progress that if two possible
indexes have the same number of
AEMs, then look to see if all
components are used in AEMs for any
of the indexes.
Single Index Rules – Rule 4
❂ Progress assumes that an index with all
components chosen will be a smaller
bracket than an index where not all the
components are chosen.
Single Index Rules – Rules 5 to 7
❂ Rule 5 – Sort Matches
• Progress tries to minimize sorting
❂ Rule 6 – Primary Index
• If nothing is better and it is still available,
Progress will use the primary index
Single Index Rules – Rules 5 to 7
❂ Rule 7 – First Index Alphabetically
• If the primary index has been disqualified
when compared to other indexes, Progress
chooses the first index alphabetically of the
indexes remaining.
Counting Records
❂ A quick and easy way to count records
is to use the SQL SELECT statement
with the COUNT(*) function.
Counting Records
/*cntsql.p */
form with frame a.
XREF reference
...SEARCH school.student name
Compiling with XREF
/* mltidx.p */
XREF reference
...SEARCH school.student name
...SEARCH school.student country-code
Compiling with XREF
/* whlidx.p */
XREF reference
...SEARCH school.student student-id WHOLE-INDEX
Applying Indexing Rules
/* idx2.p */
end.
Applying Indexing Rules
❂ Only the postalcode index is used
since all its components are utilized, but
only the first component of the index
name is used.
Applying Indexing Rules
/* idx7.p */
❂ Phone is the only index used since
studentid is involved in a range match,
not an equality match.
❂ Phone has more AEMs than student
id.
Applying Indexing Rules
/* idx9.p */
❂ Graduatealphalist and name are
both used since their leading
components are used in the WHERE
clause and are connected by the OR
operator.
Applying Indexing Rules
/* idx11.p */
❂ The studentid index is used twice and
will be efficient in the way it is used.
• Note that this example uses two brackets
on the same index.
Applying Indexing Rules
/* idx12.p */
❂ The studentid index is used but will
not be efficient since Progress must
search the entire table to see if there is
a student whose first name is “Bob”.
Applying Indexing Rules
/* idx30.p */
❂ Because Progress treats NE as an
inactive range match, this is the
inefficient way to retrieve records whose
dates are not unknown.
Applying Indexing Rules
/* idx31.p */
❂ Since the unknown value for date fields
sorts high, when reading records
Progress interprets LT ? as dates that
are not unknown.
• The moral of the story: use LT ? instead of
NE ? for reading all records whose dates
are not unknown.
Joining Records
❂ The rule is: Join from smallest bracket
to largest.
❂ Should records always be joined from
parent record to child?
• Most of the time, yes, but not always. It
depends on the brackets.
Joining Records
❂ With no WHERE conditions, there are
fewer parent records than child records,
so start with the parent record first.
❂ In join1.p, a student registers for more
than one course, so read the student
records first, before the registration
records.
Joining Records
/* join1.p - from parent to child */
❂ The above statement loads the indexes for
the first record buffer for query qh into the
idxseled selectionlist.
Dynamic Queries
❂ The WHOLEINDEX keyword is returned if a
particular record buffer is inefficient.
Index Xref Tool
❂ The following tool is provided by Johan
Forssblad from G4 IT AB.
❂ It loads the xref information into a database to
allow for easy analysis.
❂ The tools shows for each program, each line
of the program that has a record reading
statement.
Index Xref Tool
❂ On each line, it show the records read and
the corresponding indexes selected.
❂ Within the indexes selected, it shows the
components used and whether they are
bracketed or not.
Summary
❂ Now that you understand how Progress
uses indexes, you can analyze the
index usage of your applications for
optimal performance.
❂ You will also be better equipped to
design indexes for new applications.
❂ If you are not sure what index is
selected, check the XREF listing.