Quantcast
Channel: Recent Questions - Stack Overflow
Viewing all articles
Browse latest Browse all 12111

Get one value from the last row of a table, using an index

$
0
0

I have two tables, which are illustrated by the following example.

CREATE TABLE t1(   name      VARCHAR2(50 CHAR),   status    VARCHAR2(8 CHAR),   CONSTRAINT t1_pk PRIMARY KEY(name));CREATE TABLE t2(   id             NUMBER NOT NULL,   name           VARCHAR2(50 CHAR),   finished_at    DATE,   status         VARCHAR2(8 CHAR),   CONSTRAINT t2_pk PRIMARY KEY(id));CREATE INDEX ix_t2_last   ON t2(name, finished_at);

Now I would like to get the values from table T1 with the value of the column status from table 'T2' for a given 'name' for the record that has the highest value in finished_at.

The following select statement is to illustrate the question.

SELECT name,       status,       (  SELECT t2.status            FROM t2           WHERE t2.name = t1.name        ORDER BY t2.finished_at           FETCH FIRST ROW ONLY)  FROM t1 WHERE t1.name = :name;

The actual question is the following:Is there a way to formulate the statement in such a way that the index on T2 is not only used for a range scan with the name, but that the fact that the column finished_at is also indexed is also used?

The best execution plan I get is:

-----------------------------------------------------------------------------------------------------------------------------------------------------------------| Id  | Operation                     | Name       | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time   | A-Rows |   A-Time   | Buffers |  OMem |  1Mem |  O/1/M   |-----------------------------------------------------------------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT              |            |      1 |        |       |     4 (100)|          |      1 |00:00:00.01 |       2 |       |       |          ||*  1 |  VIEW                         |            |      1 |      1 |    31 |     3   (0)| 00:00:01 |      1 |00:00:00.01 |     107 |       |       |          ||*  2 |   WINDOW BUFFER PUSHED RANK   |            |      1 |      1 |    20 |     3   (0)| 00:00:01 |      1 |00:00:00.01 |     107 |  2048 |  2048 |     1/0/0||   3 |    TABLE ACCESS BY INDEX ROWID| T2         |      1 |      1 |    20 |     3   (0)| 00:00:01 |   9999 |00:00:00.01 |     107 |       |       |          ||*  4 |     INDEX RANGE SCAN          | IX_T2_LAST |      1 |        |       |     2   (0)| 00:00:01 |   9999 |00:00:00.01 |      67 |       |       |          ||   5 |  TABLE ACCESS BY INDEX ROWID  | T1         |      1 |      1 |    10 |     1   (0)| 00:00:01 |      1 |00:00:00.01 |       2 |       |       |          ||*  6 |   INDEX UNIQUE SCAN           | T1_PK      |      1 |      1 |       |     0   (0)|          |      1 |00:00:00.01 |       1 |       |       |          |-----------------------------------------------------------------------------------------------------------------------------------------------------------------Query Block Name / Object Alias (identified by operation id):-------------------------------------------------------------   1 - SEL$1 / from$_subquery$_002@SEL$3   2 - SEL$1   3 - SEL$1 / T2@SEL$1   4 - SEL$1 / T2@SEL$1   5 - SEL$2 / T1@SEL$2   6 - SEL$2 / T1@SEL$2Predicate Information (identified by operation id):---------------------------------------------------   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=1)   2 - filter(ROW_NUMBER() OVER ( ORDER BY "T2"."FINISHED_AT")<=1)   4 - access("T2"."NAME"=:B1)   6 - access("T1"."NAME"=:NAME)

Of course I can create a different index, if needed. ;-)

Since there are many rows for a given name in T2 a range scan will result in too many buffer gets.


Viewing all articles
Browse latest Browse all 12111

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>