You are on page 1of 81

BID207 Understanding Sybase IQ Optimizer

(or What is that Query Plan Telling Me?)

Lou Stanton
Principal System Consultant
stanton@sybase.com / (301) 896-1733
August 2003
Query Processing and Query Plans

 In this presentation -
 Show you how Sybase IQ Processes Queries
 Show methods for viewing Query Plans
 Understanding and Interpreting Query Plans
 How to influence Query Execution
 Discuss general Performance and Tuning tips

 This presentation is Sybase IQ 12.5 specific


 Query plans were enhanced to provide more detail
 New features in v12.5 will be addressed
By the End of this Presentation You Will Know …

 How to obtain and interpret Query Plans

 How much (or little) the optimizer knows about


your data

 How important indexes are to Query Performance

 The importance of table and database design


Why are Query Plans Important?

 You suspect (or know) a query runs poorly


 Query plans can help you investigate the problem

 You’re not sure you have the best indexes for a query
 Query plans tell you what indexes are used in a query
Query Execution Phases in Sybase

 Upon submission of a query


 Syntax and Permissions are Checked
• Performed by the ASA front-end
 Query is Parsed
• Broken down into object codes
 Query is Optimized
• Most efficient execution method is determined
• Query Plan is created
 Query is executed
 Resources are cleaned up
Sybase IQ Query Execution

Server Front End


Shared with ASAnywhere (ASA)
Handles Connections Query Plan
Parses Incoming Statements
Cross-DB Decomposition (CIS)
Security Checking
Java Support Optimizer
Stored Procedures Predicate Inference
Predicate Selectivity Estimation
Join Optimization
Grouping Algorithm Selection Run-Time Engine
Subquery Optimization Prefetch Manager
Index Access Selection Predicate Execution
Tuple (Row) Projection
Join Execution
Grouping Execution
Sorting
Subquery Execution
How do I See a Query Plan?

 Query Plans are Generated -


 In the IQ Message File
 As HTML Pages (if requested) in a separate file

 Set Option Commands used with Query Plans


 Usually set as Temporary Options
 Example:
Set Temporary Option Query_Detail = ‘On’;
 v12.5 Query_Plan option is ‘ON’ by default
 Query Plan appears in the IQ Message File
 You may turn this option off, if desired
Database Options for Query Plans

 Query_Plan = ‘On’ (default ‘On’)


 Provides a Basic Query Execution plan in the IQ Message File
 May not provide enough detail

 Query_Detail = ‘On’ (default ‘Off’)


 More detailed information in a Query Plan (Recommended)
 Must be used with Query_Plan or Query_Plan_As_HTML

 Query_Plan_As_HTML = ‘On’ (default ‘Off’)


 Creates Query Plan as an external HTML file
More Database Options for Query Plans

 Query_Plan_After_Run = ‘On’ (default ‘Off’)


 Delays creating the query plan until query completes

 Query_Timing = ‘On’ (default ‘Off’)


 Includes execution times at each stage of the query
 Must be used with Query_Plan_After_Run

 Query_Name = ‘query_name’ (default ‘’)


 Prints name provided in the Query Plan or as part of the
file name (for HTML Query Plans)

 NoExec = ‘On’ (default ‘Off’)


 Creates Query Plan but does not execute the query
HTML Query Plans

 Since HTML plans are easier to read these will be


used in this presentation
 Query_Detail will also be set ‘On’ for all examples

 When you specify Query_Plan_As_HTML = ‘On’


 File will be written in the directory with the Database File (.db)
 The File name that is produced -
• Prefaced with User Name, Date and Time
– Also contains the “Query Name” if specified
• has a “.html” file extension and is opened with a browser
Simple Example of HTML Query Plan File

Set temporary option Query_Name =‘stanton’;


Select count(*) from Central_Fact_Table;

 HTML file generated in Database File Directory


Query Plan (HTML) Output – Two Parts

1) Query Tree

2) Query Detail
HTML Query Plan – The Query Tree

Estimated Rows
Moving Up the Tree
Node Type
And Number

The Node Number (underlined) is a hot link


to the Nodes below in the Query Detail
Query Tree and Nodes

 Query Tree is a representation of the Query Plan


 Consists of Nodes representing execution plan steps
 Nodes are numbered sequentially and identified by type
• Some housekeeping nodes are not displayed so there may
be gaps in the Node number sequence
 Query Tree also displays the estimated number of rows
flowing up the branches between nodes

 The Query Tree is displayed inverted


 As you examine a Query Plan you will see the last node at the
top of the Query Tree – usually the Root Node
 Leaf Nodes are typically at the bottom of the tree (but will
appear throughout the tree if there are many tables)
A More Complex Query Tree

Leaf Nodes
Nodes - General

 Header Shows the Node Number and Node Type

 Child Node(s) (if any)


 Node(s) that ‘feed’ this node
 Hot link to the Child Node
(Leaf Nodes rarely have children)

 Estimated Result Rows


 Number of rows the optimizer thinks
will come out of this Node
 Actual Row Counts are shown with
Query_Plan_After_Run = ‘On’
Some Node Types (there are others)

 Root  Join
 Scrolling Cursor Store  Hash (HJ)
 Filter  Hash Pushdown (HJPD)
 Group By
 Nested Loop (NL)
 Sort
 Nested Loop Pushdown
(NLPD)
 Hash
 Sort-Merge (SM)
 Indexes
 Sort-Merge Pushdown
 Order By (SMPD)
 Store  Cartesian
 Semi-join Filter Filler  Subquery
 Leaf  Union All
Node Details

 Some Nodes Contain a Wealth of Information


 Detail in other nodes is not as important

 Nodes to Concentrate On -
 Root
 Leaf
 Join
 Group By
 Filter
Root Node (only with Query_Detail = ‘ON’)

Node Detail
• Child Node
• Query Name (if any)
• User Name (login)
• Temp Space Used
• Num of Users in Server
• Num of CPUs

• Database Options Set

• Output from this node


Examining the Root Node

 Number of ‘Active’ users


 Many Active users will have an effect on query response
 Optimizer may choose a different Query Plan depending upon
#CPU, IQ Cache Size and Number of Active Users
 Temp Space Usage
 Is the space required greater than the Temp Cache Size?
 It may indicate Temp Cache is paging to disk
 Database Options may affect the Query Plan
 A user or dba may have set options influencing joins,
aggregation or server behavior
Leaf Nodes

 A Leaf Node Represents an IQ Table


 Several Types of Leaf Nodes
 (Regular) Leaf
 Aggregation Leaf
 Grouping Leaf
 Order Leaf
 Leaf Nodes can have a wealth of information
 Table Row Count
 Query Predicate(s) - WHERE clause search arguments
• Indexes available on columns used in predicates
• Estimated Selectivity of predicates
• Usefulness of the predicate
• Index used by the predicate
 Output Columns from the table
Leaf Node Discussion

 Portion of a table used in a query is a ‘found set’


 The optimizer knows that Table ‘A’ has X rows
 If there are no predicates on columns in the table we are done
• We just need the column(s) from the table for the query
• Rows are passed up the Query Tree to the next Node
 If predicates exist Optimizer must determine the
best order to execute them
 If only one predicate then there is no decision
 With multiple predicates each one is evaluated and assigned a
USEFULNESS Score
• Usefulness Score is a scale of 0 to 10 (10 = Most Useful)
IQ Optimizer - Usefulness

 Usefulness is used to rank the predicates for


execution order
 Predicate with the highest value (score) is executed first
 Remaining predicates executed in descending order of
Usefulness

 What determines Usefulness Score?


 How well a Query Predicate will reduce the found set (Table)
 Factors influencing Usefulness Score -
• Type of Query Predicate
• Index(es) available for Column
• Optimized FP indexes on Column
• How fast the predicate can be executed
Leaf Node Discussion – Example Query

 Single table (147 MM rows) - 5 Predicates


 What is the best order to execute these ??
 What do you need to know to decide ??

select paid_amt
from central_fact_table
Where elig_beg_date >= '2000-01-01' and
MEMBER_GENDER = 'M' and
MEMBER_DOB < '1950-01-01' and
complication = 'OUTPATIENT' and
service_rollup = 'Neoplasms'
Optimizer Search Criteria – NO indexes

 Rules the optimizer uses (IQ 12.5) when NO indexes


exist for a query predicate (partial list)

Percent of table
Query Operator Returned (Estimated)
Equality (=) 20%
Open Range (>) 40%
Between 40%
Like (%) 20%
Inter-column equality (t.a = t.b) 30%
Inter-column comparison (t.a < t.b) 50%
(You will see these estimates in Query Plans)
Leaf Node Discussion–Indexes on Predicates

 If a ‘useable’ index exists on a predicate it can


provide more information about a column
 Depends on the type of predicate and the index type(s)

 Beware of some functions used on a column as


they will negate the use of the index!
 Substring( t.a, 5, 5 ) = ‘fghijk’
 May result in a Column Scan
 The optimizer will use the default rule for rows returned
(20% of the rows for an Equality search)
Query Predicate Operators

 Equality and Inequality ( = , != )


 Includes IN and NOT IN lists

 Ranges ( <, >, <=, >=, Between)


 Including NOT (!)

 Like ( % ) or Not Like


 Contains

 IS [NOT] NULL
Query Predicate Operators and IQ Indexes

 Equality and Inequality ( = , != ) LF and HG


 Includes IN and NOT IN lists

 Ranges ( <, >, <=, >=, Between) DATE, HNG,


 Including NOT (!) LF and HG

 Like ( % ) or Not Like


FP and WD
 Contains

 IS [NOT] NULL Null Bit


The Enumerated Indexes – HG and LF

 These indexes provide exact data distribution


counts to the optimizer -
 The number of distinct values for a column and
 The number of rows for each value

 When columns with these indexes are used in


certain query predicates they provide the optimizer
with exact row counts that will be found
 Equality and Inequality operators (also IN List, NOT IN List)

 LF/HG indexes also help Range Searches by


providing counts of distinct values within the
Range
Other Indexes

 The other indexes used in query predicates locate


the rows to satisfy the query
 They do not provide counts of rows to the optimizer
 You will see them referenced in Leaf Nodes

 If Enumerated indexes or Optimized FP indexes are


not available then Optimizer can only guess the
number of rows that satisfy the predicate
 Optimizer will use the defaults (discussed earlier)
 Later you will see how to help the optimizer avoid bad guesses
Query Example – Leaf Node

 Back to our Query …

select paid_amt
from central_fact_table
Where
elig_beg_date >= '2000-01-01' and
MEMBER_GENDER = 'M' and
MEMBER_DOB < '1950-01-01' and
complication = 'OUTPATIENT' and
service_rollup = 'Neoplasms'
The Leaf Node for This Query

This is a large
Leaf Node !
(about 2 pages)

We will examine
it in parts
Leaf Node (Part 1) Row Information

Estimated Result Set

(Information here is hidden for clarity)

Original Table Size


Leaf Node (Part 2) – Predicate Evaluation

 Each predicate for the table is evaluated


 If an HG/LF index exists it provides Selectivity Statistics
(number rows returned as a Percentage of the Table)
 Usefulness Score is assigned based on found set size
 The smaller the set, the more useful the predicate

.0001 % of the table is returned


That is very useful!!
Each Predicate is Evaluated and Ranked

Selectivity

Usefulness

Index Used
Usefulness For Each Predicate Assigned

 Predicates are ranked by Usefulness

Query Predicate Selectivity Usefulness


==========================================
service_rollup = 'Neoplasms' .001 9.99
MEMBER_GENDER = 'M' .389 9.61
elig_beg_date >= '2000-01-01' .764 6.23
MEMBER_DOB < '1950-01-01' .389 5.61
complication = 'OUTPATIENT' .200 2.80

This looks like a ‘Guess’ – 20% for an Equality


Est. Row Count from the Table is Derived from
Selectivity Estimates Applied to all the Predicates
 Estimates are applied to each subsequent
predicate to determine the table’s Found Set
 Condition 1: 149,178,536 * 0.001995 = 297,587 rows
 Condition 2: 297,587 * 0.389099 = 115,791 rows
 Condition 3: 115,791 * 0.764858 = 88,564 rows
 Condition 4: 88,564 * 0.389793 = 34,521 rows
 Condition 5: 34,521 * .2000000 = 6,904 rows
Optimized FP Indexes (1 and 2 byte FPs)

 Play important roles in 12.5 Engine


 Provide distinct counts in the absence of LF/HG index
 Help with Range Searches, LIKE predicates, push-down join
conditions, and predicates containing an expression on a
column such as - SUBSTR(t.x, 1, 2) = 'TE'
 Move data up the query tree faster (fewer bytes to move)
 12.5 Query Plans display usage of these FPs

 12.5 has new Database Option to “auto-create”


Optimized FP indexes for all columns
 MINIMIZE_STORAGE (default OFF)
Minimize_Storage Option

 Late addition to 12.5 Release


 Option description did not make first printing of any IQ Docs
 Look in the Release Bulletin for 12.5 for details
 When set ‘ON’ has the affect of IQ Unique(255) for
all columns in tables you create
 As data is loaded column FP index will ‘roll over’ to 2 byte and
then Flat FP index as necessary
 Highly recommended for all tables < 1000 columns
 After Upgrading to IQ 12.5
 Set Option ON and create a new table
 Load from old table into new table using INSERT
 Drop old table and rename new table
Optimized FP Indexes – Changes in 12.5

 Optimizer no longer considers IQ Unique() value in


Create Table for approx distinct counts of a column
 12.4.x optimizer looked at the value in absence of HG/LF index
 That value could have changed over time and been way wrong
 There is no method to ‘update’ the IQ Unique() value

 In 12.5 - Uses Optimized FP indexes to


 Improve Query Performance
 Reduce Data Storage in IQ Store
• Many cases of dramatic storage reduction
• Fully Indexed IQ data = 50% of input data size
Leaf Node – Predicate Information

 There is more detail on predicates in the Leaf Node


 This shows how much IQ knows about the data

elig_beg_date >= '2000-01-01'


• HG and Date Index on column
• 8578 Distinct values
• 1096 Values satisfy query
• Column stored as FP(2)
Back to Our Query Example

 Was the Optimizer Estimate correct?

 Use Query_Plan_After_Run option


 Delays the printing of the Query Plan until Query Completes

 New details appear in the Query Plan After Run


 Estimated and Actual Row Counts at each Node
 Estimated and Actual Temp Space Used
Sample Query - Query Plan After Run

 Row Estimate
 Off by a factor or 72.6
 Temp Space Usage
 Just slightly below actual

 Questions …
 Why is row estimate wrong?
 Is this a problem?
Row Estimates

 Several Reasons for Wrong Estimates


 Method used to derive estimate is not perfect
• Assumes even distribution of data and
• Predicates are not correlated
 One Predicate was a Guess (no useable index for column)
• Importance of HG/LF indexes cannot be stressed enough

 Wrong Estimates May NOT be a Problem


 Nodes using HASH tables are more sensitive to row counts
• There are row limitations and performance implications
 Sort Nodes are not sensitive to wrong estimates
Corrective Action and Results

 Created LF Index on 149MM row table


 Took 110 Seconds (Sun 64 w/ 900 MHZ cpu)

 New index is more Selective (and Useful)

 Estimates are much closer to reality


 This is about as close as we can get for now
Query Plan After Index Added
User Supplied Estimates for Queries

 For cases where no index can be used for a query


 You can advise the optimizer the percentage of rows that will
be returned by the predicate
Syntax: Add percentage to predicate after a comma within
parentheses()

Select count(*) from central_fact_table


Where (service_rollup like ‘%Poison%’ , .003)

 This example - .00003 percent of rows match


 Value provided is a percentage
Query Plan - No Estimate Provided
Query Plan with User Supplied Estimate
Leaf Nodes – Wrap Up

 Show Indexes Available and Indexes Used


 Order of Predicate Execution
 Selectivity and Usefulness of Indexes
 Estimated and Actual Row Counts from Table
 Other
 Output Columns from Table

 Next Node Type: Join Nodes


Join Nodes – Seven Type of Joins in IQ

 Hash (HJ)  Hash Pushdown (HJPD)

 Nested Loop (NL)  Nested Loop Pushdown (NLPD)

 Sort-Merge (SM)  Sort-Merge Pushdown (SMPD)

Cartesian Nested Loop Joins

 You will see the Full Join Type Names and Abbreviations in
Query Plans

(Short description of these join types follows)


Nested Loop Joins

 Nested Loop (NL)


 Takes a join key from the larger side of the join and compare it
to each row of the smaller side

 Nested Loop Pushdown (NLPD)


 Take the join keys of the smaller side of the join into an IN list
on the large table
Hash Joins

 Use Hashing Algorithms for Joins


 This Join will be handled in Memory
 Hash Operations are Restricted by the DB Option
 MAX_HASH_ROWS – default 2,500,000 (configurable)

 Hash Joins are Sensitive to Row Estimates


 If Estimated Row Counts are too low Thrashing can occur
• Thrashing involves Disk I/O
 Server will abort a query (rollback) if thrashing becomes
excessive
 Hash_Thrashing_Percent DB Option controls this behavior
• Default = 10 (percent) and is configurable
Sort-Merge

 Classic Join Algorithm


 Sort both tables and match up the join keys
 Used for joining two large tables
 Uses Temp Cache/Store for sorting
 Accompanied with Order By Nodes for both Tables
 Where sorting is performing

 Sort-Merge Push Down


 Creates an IN List of Keys on smaller table to ‘probe’ and filter
rows from the other table
 Unique to Sybase IQ
Joins in a “Simple” Query
Join Node - General

 Has Two Child Nodes


 Shows Estimated Result Rows after joining
 Actual Row counts with Query_Plan_After_Run
 Lists the Types of Joins the Optimizer considered
 Could have picked any one in the list
 Shows Join Condition(s)
 But NOT the indexes used!
 Other information specific to the type of join
Sort-Merge Join Node (Query Tree)

• Sort-Merge Joins are usually preceded by an Order By Node


Sort-Merge Join Node (partial)

 Child Nodes
 Estimated Result Rows
 Join Types Considered

 Optimization Note

 Join Constraint
‘Push Down’ Joins

 When the Optimizer uses a Push Type join you will


see different notations in Leaf Nodes that are
‘probed’

 The Leaf for the larger side of the join is filtered by


an IN list to reduce the number of keys that flow
from that Node
Join Nodes - Performance Considerations

 Create Primary Keys on tables


 At the very least HG or Unique HG indexes on all join keys

 Use Query_Plan_After_Run to check row counts


 If estimates are are ‘way off’ then check for missing indexes in
Leaf Nodes and/or create Primary Keys
 Hash Join types are most sensitive to row estimates
 Sort-Merge, Nested Loop joins are not
Complex Query – No Primary Keys Defined

Some BIG Numbers!


Complex Query

 Query involved many join columns on large tables


 Indexes were correct for all joins and predicates
 The optimizer made very conservative estimates since it could
not accurately predicate final result set from join

 Actual results were much smaller than the estimate

 Creating Primary keys on tables changed the plan


 Result set estimates while still on the high side were decidedly
smaller
Row Estimates - Before and After Primary Key

Result Set Estimate:


7,355,725,745,151,829

New Estimate
24,396,774,363
300,000 x
smaller!
Tweaking Joins

 You can influence Join Type selection


 Database Option - Join_Preference

 You can also influence Join Order


 Database Option - Join_Optimization
Join_Preference Database Option

Default = ‘0’ (Optimizer Decides)

 ‘1’ – Prefer Sort/Merge  ‘-1’ – Avoid Sort-Merge


 ‘2’ – Prefer Nested Loop  ‘-2’ – Avoid Nested Loop
 ‘3’ – Prefer Nested Loop PD  ‘-3’ – Avoid Nested Loop PD
 ‘4’ – Prefer Hash  ‘-4’ – Avoid Hash
 ‘5’ – Prefer Hash PD  ‘-5’ – Avoid Hash PD
 ‘6’ – Prefer PreJoin  ‘-6’ – Avoid PreJoin
 ‘7’ – Prefer Sort Merge PD  ‘-7’ – Avoid Sort-Merge PD
You can only influence join type from the list of joins the server
considered in the Query Plan, otherwise it will ignore the option
(and it may just ignore it anyway!!)
Join_Preference Option

 Set Temporary Option Join_Preference = ‘-2’;


 Telling Optimizer to Avoid Nested Loop Joins
 Option value must be quoted as shown

 For problem solving and performance testing

 Use as a Temporary Option with a Query


Join_Optimization Option

 Default = ‘On’ – Optimizer Decides Join Order

 If set ‘Off’ will join tables as listed in the FROM


clause

 Use this only to diagnose obscure join


performance issues
 And use it as a Temporary Option as well
Group By Nodes

 Three types of Group By Nodes


 Group By (Hash) – for smaller result sets
• All done in memory
 Group By (Sort) – larger sets
• Will use IQ Temp Memory/dbspace for sorts
 Grouped Leaf – Grouping with indexes in a Leaf Node
• For single tables when all Group By columns are indexed

 Group By (Hash)
 Same database options apply as for joins
 2,500,000 row max (default)
Group By Nodes - General

 Have a Child Node


 Show Estimated Result Rows
 Actual rowcount if Query_Plan_After_Run = ‘On’
 Grouping Expressions Used
 But no information on indexes used
 Output columns
Group By Performance

 Index All Grouping Expressions


 LF or HG indexes needed
 They will provide the best estimates for results
 Group By (Hash) generally faster than Group By (Sort)
 Sort method will be used when optimizer is in doubt
 If estimates in child node are way under the wrong
method may be used
 Check Estimated vs Actual counts
Tweaking Group By Performance

 Like Joins, You can influence the optimizer


 Database Option: Aggregation_Preference
 Default = ‘0’ – Optimizer decides

‘1’ – Prefer Sort ‘-1’ Avoid Sort


‘2’ – Prefer Using Indexes ‘-2’ Avoid Indexes
‘3’ – Prefer Hash ‘-3’ Avoid Hash

 Use this option with care and always as a


Temporary Option
Filter Nodes

 Used with some expressions and “Having” clauses


that cannot by filtered with an index
Example:
Select diag_catgy_cd, sum(paid_amt)
From inpatient
Group By diag_catgy_cd
Having sum(paid_amt) > 10000

 The Having expression must be evaluated and filtered


after the groups are formed
Query Plan with Filter Node
Node Detail – Leaf Node

No HG/LF Index !
Node Detail –Group By (Hash)
Node detail – Filter Node
Index on Group By Column May Help

 Build on index on the Grouping Expression


 HG Index is appropriate

 Rerun The Query


New Query Plan (new HG Index)

• Grouped Leaf instead of Leaf Node and Group By(hash)


Grouped Leaf Node and Filter Node
You Should be Dangerous Now …

 We have covered Query Plans “101” for Sybase IQ

 Now you know …


 Indexes are important (always have been)
 Primary keys are important (more than ever)
 Optimized FP indexes are important (even more than ever)
 The optimizer is conservative and can be influenced

 And there is more, but we just don’t have the time


Questions

Visit the
IQ Technical Team
on the Boardwalk

Lou Stanton
stanton@sybase.com

You might also like