|
|
Question : Mixing query hints - parallel and index
|
|
I'm having some trouble mixing query hints. Seems that I can choose parallelism, or I can choose the index I want, but I can't have both. The query plans shown below illustrate my problem. I've added comments in square brackets. What have I overlooked here?
-Scott.
------------------------------------- 1> SELECT count(DISTINCT F.CLCL_ID) FROM CMC_CLCL_CLAIM_H1 F (parallel 4) 2> WHERE AS_OF_FROM_DT <= '2008-01-22' and IS_DELETED = 'N' 3> go
QUERY PLAN FOR STATEMENT 1 (at line 1). Executed in parallel by coordinating process and 4 worker processes.
STEP 1 The type of query is INSERT. The update mode is direct. Executed in parallel by coordinating process and 4 worker processes. [Parallelism is good !!]
FROM TABLE CMC_CLCL_CLAIM_H1 F Nested iteration. Index : AS_OF_DATES [No no! Why choose this key when there's another containing all the needed columns?!] Forward scan. Positioning by key. Keys are: AS_OF_FROM_DT ASC Executed in parallel with a 4-way hash scan. Using I/O Size 16 Kbytes for index leaf pages. With MRU Buffer Replacement Strategy for index leaf pages. Using I/O Size 16 Kbytes for data pages. With MRU Buffer Replacement Strategy for data pages. TO TABLE Worktable1.
STEP 2 The type of query is SELECT. Evaluate Ungrouped COUNT AGGREGATE. Executed by coordinating process.
FROM TABLE Worktable1. Nested iteration. Table Scan. Forward scan. Positioning at start of table. Using I/O Size 16 Kbytes for data pages. With MRU Buffer Replacement Strategy for data pages.
STEP 3 The type of query is SELECT. Executed by coordinating process.
------------------------------------- [Okay, I'll hint parallelism and an index that contains all the needed columns.]
1> SELECT count(DISTINCT F.CLCL_ID) FROM CMC_CLCL_CLAIM_H1 F (parallel 4 index AS_OF_DATES_SCOTT) 2> WHERE AS_OF_FROM_DT <= '2008-01-22' and IS_DELETED = 'N' 3> go
QUERY PLAN FOR STATEMENT 1 (at line 1).
STEP 1 The type of query is INSERT. The update mode is direct.
FROM TABLE CMC_CLCL_CLAIM_H1 F Nested iteration. Index : AS_OF_DATES_SCOTT Forward scan. Positioning by key. Index contains all needed columns. Base table will not be read. [Awesome! But where's my parallelism?!] Keys are: AS_OF_FROM_DT ASC Using I/O Size 16 Kbytes for index leaf pages. With LRU Buffer Replacement Strategy for index leaf pages. TO TABLE Worktable1.
STEP 2 The type of query is SELECT. Evaluate Ungrouped COUNT AGGREGATE.
FROM TABLE Worktable1. Nested iteration. Table Scan. Forward scan. Positioning at start of table. Using I/O Size 16 Kbytes for data pages. With MRU Buffer Replacement Strategy for data pages.
STEP 3 The type of query is SELECT.
1>
|
Answer : Mixing query hints - parallel and index
|
|
While the comment about update statistics is a good one - when seeing any optimiser weirdness, the first thing you should do is always a good "update index statistics [table]" (assuming ASE 11.9.2+).
That said, I think here we are seeing correct and expected behaviour.
I can't speak for whether the decision the optimiser is making in terms of the unforced index is the correct one, but forcing a covered NC index scan *cannot* be done in parallel.
You need to look at the Sybase P&T manuals in depth for the full explanation, but briefly, whenever parallel query is done prior to ASE 15.x, the parallel part is only done when reading the data pages. Any walking of the index tree is in fact done by the first worker process (WP) in the parallel family, and then the qualifying data pages are (for a hash scan, which is what you're seeing) farmed out between all WPs (including WP1, who therefore has more work to do than any of the other WPs).
This is crucial here - parallel is done only on data pages, not on index pages...
... and yet, when you do a covered NC index scan (whether forced or not), you *only* read index pages. That's the definition of a covered NC scan! And since we're only reading index pages and no data pages, and since parallel is only done on data pages and not on index pages, the optimiser has correctly recognised that whether you force parallel or not, this query can only be performed serially. It literally cannot do this in parallel even if it wanted to. 8-)
(I *think* the rules are a bit different in ASE 15+ where both hash scans, parallel query in general and the use of indexes to cover predicates have all dramatically changed, but from the showplans you posted you aren't using ASE 15.0.x, so I'm safe. 8-) )
To get back to your original question: I believe your force syntax is correct - you can force multiple query attributes at once.
That said, forcing indexes or parallelism is generally a sign of something loopy going on. I'd be very keen to see if anything changes after you run "update index statistics [table] using 100 values" (assuming a large table).
Although I think my explanation above might actually have solved your other embedded question about why it didn't pick the covering NC index for you - the optimiser might have thought that a 4-way NC hash scan was going to be faster than a 1-way serial covered query. Have you actually timed it either way? Maybe the optimiser did exactly the right thing for you! 8-)
|
|
|
|
|