Discussion:
Index contains all needed columns. Base table will not be read.
(too old to reply)
1dg618
2011-10-25 22:46:08 UTC
Permalink
I created two similar tables. I created a unique clusterd index on
both tables, but the order of the columns are different. One index has
the date first where the other index has the date last. I'm searching
the tables using the date...

++++++

unique clustered index

date
first_id
second_id

I get this in the plan:

Positioning by key.
Keys are:

++++++

unique clustered index

first_id
second_id
date

I get this in the query plan:

Positioning by key.
Index contains all needed columns. Base table will not be read.
Keys are:

I noticed that I get the "Index contains all needed columns. Base
table will not be read." which is better performance-wise then not
getting it.

When creating indexes how do you guarantee not reading the base table.
It seems like the first case did have to read the base table?
Antony
2011-10-25 23:30:19 UTC
Permalink
Can you post the SQL and two query plans in full? Then we might be able to help further...
Derek Asirvadem
2011-10-29 06:08:51 UTC
Permalink
Post by 1dg618
When creating indexes how do you guarantee not reading the base table.
It seems like the first case did have to read the base table?
1. In order to answer fully, yes, we need the CREATE TABLE/INDEX
statements, and the SQL used.

2. If this is from your other question, then I will assume:
- both tables are APL
- both tables are ~700 million rows
- the only difference in the CI: columns are the same but the order is
as specified in your post
- the SQL used is identical, except for the table name.

The answer is:
- you cannot guarantee, but you can imply; then hint; then force ASE
to use the index only, and skip reading the "base table"
- but the fact the it refers to the "base table" implies that it is
using an NCI or the table is not APL. (see, we do need the CREATE
TABLEstatement.) ASE generally refers to the "base table as an
euphemism for the heap, not the CI.
- so, from the small info we have, it looks like you have a NCI on one
table and not the other (or one table is APL, the other is not).
Obviously when running tests like this, you need to ensure that you
have the same indices, etc, except for the specific difference that
you are testing for.
- it is always desirable to service the query from an index (any index
that can). This is called a Covered Query. The requirement of course
is, that all the sargs used must be columns in that one index, and no
data columns are requested. Tht is basically all you have to do.
- if you *know* you have an index that can service the query and avoid
the "base table", sure, you can instruct it to use the index via
FROM mytable (INEX index_name)

Regards
Derek
1dg618
2011-10-31 16:37:43 UTC
Permalink
CREATE TABLE first
(
one_id INT NOT NULL,
two_id INT NOT NULL,
date DATETIME NOT NULL,
junk_id INT NOT NULL,
CONSTRAINT first_pkc_1
PRIMARY KEY CLUSTERED ( one_id, two_id, date, junk_id ) on
'default'
)
LOCK allpages ON 'default' partition BY roundrobin 1
GO

CREATE TABLE second
(
junk_id INT NOT NULL,
junk_desc varchar(255) NULL,
CONSTRAINT second_pkc_1
PRIMARY KEY CLUSTERED ( junk_id ) on 'default'
)
LOCK allpages ON 'default' partition BY roundrobin 1
GO

select
a.one_id,
a.two_id,
a.date,
b.junk_id
from
first a
left join second b on a.junk_id = b.junk_id
where
a.date >= '20091020'
and
a.date <= '20091120'
and
a.one_id = 120326
and
a.two_id = 1

QUERY PLAN FOR STATEMENT 1 (at line 1).
STEP 1
The type of query is SELECT.
5 operator(s) under root
|ROOT:EMIT Operator (VA = 5)
|
| |RESTRICT Operator (VA = 4)(0)(0)(0)(0)(11)
| |
| | |MERGE JOIN Operator (Join Type: Left Outer Join) (VA =
3)
| | | Using Worktable2 for internal storage.
| | | Key Count: 1
| | | Key Ordering: ASC
| | |
| | | |SORT Operator (VA = 1)
| | | | Average Row width is 22.000000
| | | | Using Worktable1 for internal storage.
| | | |
| | | | |SCAN Operator (VA = 0)
| | | | | FROM TABLE
| | | | | first
| | | | | a
| | | | | Using Clustered Index.
| | | | | Index : first_pkc_1
| | | | | Forward Scan.
| | | | | Positioning by key.
| | | | | Keys are:
| | | | | one_id ASC
| | | | | two_id ASC
| | | | | date ASC
| | | | | Using I/O Size 16 Kbytes for data pages.
| | | | | With MRU Buffer Replacement Strategy for
data pages.
| | |
| | | |SCAN Operator (VA = 2)
| | | | FROM TABLE
| | | | second
| | | | b
| | | | Using Clustered Index.
| | | | Index : XPKsecone
| | | | Forward Scan.
| | | | Positioning at index start.
| | | | Index contains all needed columns. Base table
will not be read.
| | | | Using I/O Size 16 Kbytes for index leaf pages.
| | | | With LRU Buffer Replacement Strategy for index
leaf pages.

Total estimated I/O cost for statement 1 (at line 1): 77052.


The first table is filled with about 300 million records and the
second table is filled with about 2 million records.

According to the show plan, we it is using work tables and what do
work tables mean?

"Using Worktable2 for internal storage." and "Using Worktable1 for
internal storage."

Is there anything I can do to get rid of the work tables?
Derek Asirvadem
2011-11-02 01:06:15 UTC
Permalink
This is a completely different question. You have also posted this
new question in the other thread. I have answered there. What remains
Post by Derek Asirvadem
- but the fact the it refers to the "base table" implies that it is
using an NCI or the table is not APL. ASE generally refers to the
"base table" as an euphemism for the heap, not the CI.
| | | |SCAN Operator (VA = 2)
| | | | FROM TABLE
| | | | second
| | | | b
| | | | Using Clustered Index.
| | | | Index : XPKsecone
| | | | Forward Scan.
| | | | Positioning at index start.
| | | | Index contains all needed columns. Base table
will not be read.
Although the CI B-Tree and leaf-level entries (which are the data
rows) are located in a single data structure, they are in separate
areas. I will assume the second is the APL table you have provided
partial DDL for. Here the QP is saying, it will read the B-Tree only,
and not read the leaf-level.

Regards
Derek

Loading...