почему в плане есть SORT (ORDER BY STOPKEY) ?

Журавлев Денис
Дата: 24.11.2009 17:36:32
SQL> select *
  2    from (SELECT /*+index_desc(STA_1 T_STATEMENTDEN)*/ STA_1.STATEMENT_ID,
  3                 STA_1.BALANCE_ON_ENTRY,
  4                 STA_1.BALANCE_ON_EXIT
  5            FROM T_STATEMENT STA_1
  6           WHERE (STA_1.OBJECT_MAIN, STA_1.STATEMENT_TYPE_ID) = (select '40817810614001014481', 1 from dual)
  7             AND (STA_1.STATEMENT_ID < 23739975)
  8           ORDER BY STA_1.STATEMENT_ID DESC)
  9   where rownum <= 1;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=1 Bytes=39)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=5 Card=6 Bytes=234)
   3    2       SORT (ORDER BY STOPKEY) (Cost=5 Card=6 Bytes=246)
   4    3         TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'T_STATEMENT' (Cost=4 Card=6 Bytes=246)
   5    4           INDEX (RANGE SCAN DESCENDING) OF 'T_STATEMENTDEN' (NON-UNIQUE) (Cost=3 Card=6)
   6    5             TABLE ACCESS (FULL) OF 'DUAL' (Cost=20 Card=8168)

ну не может = (select) вернуть больше одной строки, даже если Card не 8168, а 1, все равно тоже самое.

SQL> select *
  2    from (SELECT STA_1.STATEMENT_ID,
  3                 STA_1.BALANCE_ON_ENTRY,
  4                 STA_1.BALANCE_ON_EXIT
  5            FROM T_STATEMENT STA_1
  6           WHERE (STA_1.OBJECT_MAIN = '40817810614001014481')
  7             and (STA_1.STATEMENT_TYPE_ID = 1)
  8             AND (STA_1.STATEMENT_ID < 23739975)
  9           ORDER BY STA_1.STATEMENT_ID DESC)
 10   where rownum <= 1;

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE (Cost=4 Card=1 Bytes=39)
   1    0   COUNT (STOPKEY)
   2    1     VIEW (Cost=4 Card=6 Bytes=234)
   3    2       TABLE ACCESS (BY GLOBAL INDEX ROWID) OF 'T_STATEMENT' (Cost=4 Card=6 Bytes=246)
   4    3         INDEX (RANGE SCAN DESCENDING) OF 'T_STATEMENTDEN' (NON-UNIQUE) (Cost=3 Card=6)

9.2.0.8
andrey_anonymous
Дата: 24.11.2009 17:43:33
Журавлев Денис

ну не может = (select) вернуть больше одной строки, даже если Card не 8168, а 1, все равно тоже самое.

Ну не написал oracle отдельный метод соединения для такого условия... А зачем, кстати, Вам именно так?
Почему не просто (a,b) in (('a','b')) ?
ESM
Дата: 24.11.2009 17:48:48
Уважаемый Денис!
Пожалуйста, обратитесь в службу поддержки.
Журавлев Денис
Дата: 24.11.2009 18:02:45
andrey_anonymous

А зачем, кстати, Вам именно так?
у меня запрос не из дуала, но возвращает он одну строку.
конститент гетс в варианте с sort 37, а без него два запроса 4+5=9


andrey_anonymous
Почему не просто (a,b) in (('a','b')) ?
одна строка потому что.

В 10.2.0.4 тоже самое.
SQL> select * from (
  2  SELECT *
  3    FROM acc_credbatch_state
  4   WHERE CBS_CRB_ID = (select '222222' from dual)
  5     AND (CBS_DT_BUH < sysdate)
  6   ORDER BY CBS_DT_BUH DESC)
  7   where rownum <=1;

------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                     |     1 |   105 |    12   (9)| 00:00:01 |
|*  1 |  COUNT STOPKEY                 |                     |       |       |            |          |
|   2 |   VIEW                         |                     |     8 |   840 |    12   (9)| 00:00:01 |
|*  3 |    SORT ORDER BY STOPKEY       |                     |     8 |   592 |    12   (9)| 00:00:01 |
|   4 |     TABLE ACCESS BY INDEX ROWID| ACC_CREDBATCH_STATE |     8 |   592 |     9   (0)| 00:00:01 |
|*  5 |      INDEX RANGE SCAN          | CBS_DT_BUH_IDX      |     8 |       |     3   (0)| 00:00:01 |
|   6 |       FAST DUAL                |                     |     1 |       |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
   1 - filter(ROWNUM<=1)
   3 - filter(ROWNUM<=1)
   5 - access("CBS_CRB_ID"=TO_NUMBER( (SELECT /*+ */ '222222' FROM "SYS"."DUAL" "DUAL")) AND "CBS_DT_BUH"<SYSDATE@!)

SQL> select * from (
  2  SELECT *
  3    FROM acc_credbatch_state
  4   WHERE CBS_CRB_ID = '222222'
  5     AND (CBS_DT_BUH < sysdate)
  6   ORDER BY CBS_DT_BUH DESC)
  7   where rownum <=1;
------------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |                     |     1 |   105 |     5   (0)| 00:00:01 |
|*  1 |  COUNT STOPKEY                 |                     |       |       |            |          |
|   2 |   VIEW                         |                     |     2 |   210 |     5   (0)| 00:00:01 |
|   3 |    TABLE ACCESS BY INDEX ROWID | ACC_CREDBATCH_STATE |     8 |   592 |     5   (0)| 00:00:01 |
|*  4 |     INDEX RANGE SCAN DESCENDING| CBS_DT_BUH_IDX      |     2 |       |     3   (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------
   1 - filter(ROWNUM<=1)
   4 - access("CBS_CRB_ID"=222222 AND "CBS_DT_BUH"<SYSDATE@!)
Журавлев Денис
Дата: 24.11.2009 18:05:04
ESM
Уважаемый Денис!
Пожалуйста, обратитесь в службу поддержки.
типа мне на форуме уже нельзя писать?
ESM
Дата: 24.11.2009 19:40:33
Приводить на форуме номер счета клиента точно не следовало...

По поводу SORT (ORDER BY STOPKEY): если посмотрите на запрос внимательнее, вопрос ПОЧЕМУ отпадёт.
Журавлев Денис
Дата: 24.11.2009 22:12:01
ESM
Приводить на форуме номер счета клиента точно не следовало...

По поводу SORT (ORDER BY STOPKEY): если посмотрите на запрос внимательнее, вопрос ПОЧЕМУ отпадёт.
Уважаемый, я через целых 30 секунд понял на что Вы намекаете. Ох как мне тяжело.
Nikolay Kalmarskiy
Дата: 24.11.2009 22:35:47
+ ЭТО делается так:-
SQL> 
SQL> set linesize 120
SQL> 
SQL> create table pt2814 (a number, e date);

Table created.

SQL> 
SQL> create index pt2814_ndx on pt2814(a, e);

Index created.

SQL> 
SQL> set autotrace on explain
SQL> 
SQL> alter session set optimizer_mode=FIRST_ROWS;

Session altered.

SQL> 
SQL> select * from (select * from pt2814 where a = (select '0' from dual e) and e < sysdate order by e desc) where rownum < 2;

no rows selected


Execution Plan
----------------------------------------------------------                                                              
Plan hash value: 366344820                                                                                              
                                                                                                                        
--------------------------------------------------------------------------------------                                  
| Id  | Operation               | Name       | Rows  | Bytes | Cost (%CPU)| Time     |                                  
--------------------------------------------------------------------------------------                                  
|   0 | SELECT STATEMENT        |            |     1 |    22 |     4  (25)| 00:00:01 |                                  
|*  1 |  COUNT STOPKEY          |            |       |       |            |          |                                  
|   2 |   VIEW                  |            |     1 |    22 |     4  (25)| 00:00:01 |                                  
|*  3 |    SORT ORDER BY STOPKEY|            |     1 |    22 |     4  (25)| 00:00:01 |                                  
|*  4 |     INDEX RANGE SCAN    | PT2814_NDX |     1 |    22 |     2   (0)| 00:00:01 |                                  
|   5 |      FAST DUAL          |            |     1 |       |     2   (0)| 00:00:01 |                                  
--------------------------------------------------------------------------------------                                  
                                                                                                                        
Predicate Information (identified by operation id):                                                                     
---------------------------------------------------                                                                     
                                                                                                                        
   1 - filter(ROWNUM<2)                                                                                                 
   3 - filter(ROWNUM<2)                                                                                                 
   4 - access("A"=TO_NUMBER( (SELECT '0' FROM "SYS"."DUAL" "E")) AND                                                    
              "E"<SYSDATE@!)                                                                                            
                                                                                                                        
Note                                                                                                                    
-----                                                                                                                   
   - dynamic sampling used for this statement                                                                           

SQL> 
SQL> 
SQL> select * from (select * from pt2814 where a = (select '0' from dual e) and e < sysdate order by a desc, e desc) where rownum < 2;

no rows selected


Execution Plan
----------------------------------------------------------                                                              
Plan hash value: 2574937940                                                                                             
                                                                                                                        
--------------------------------------------------------------------------------------------                            
| Id  | Operation                     | Name       | Rows  | Bytes | Cost (%CPU)| Time     |                            
--------------------------------------------------------------------------------------------                            
|   0 | SELECT STATEMENT              |            |     1 |    22 |     3   (0)| 00:00:01 |                            
|*  1 |  COUNT STOPKEY                |            |       |       |            |          |                            
|   2 |   VIEW                        |            |     1 |    22 |     3   (0)| 00:00:01 |                            
|*  3 |    INDEX RANGE SCAN DESCENDING| PT2814_NDX |     1 |    22 |     2   (0)| 00:00:01 |                            
|   4 |     FAST DUAL                 |            |     1 |       |     2   (0)| 00:00:01 |                            
--------------------------------------------------------------------------------------------                            
                                                                                                                        
Predicate Information (identified by operation id):                                                                     
---------------------------------------------------                                                                     
                                                                                                                        
   1 - filter(ROWNUM<2)                                                                                                 
   3 - access("A"=TO_NUMBER( (SELECT '0' FROM "SYS"."DUAL" "E")) AND "E"<SYSDATE@!)                                     
       filter("E"<SYSDATE@! AND "A"=TO_NUMBER( (SELECT '0' FROM "SYS"."DUAL" "E")))                                     
                                                                                                                        
Note                                                                                                                    
-----                                                                                                                   
   - dynamic sampling used for this statement                                                                           

SQL> 
SQL> 
SQL> drop table pt2814;

Table dropped.

SQL> 
SQL> exit;
Журавлев Денис
Дата: 25.11.2009 08:57:13
Nikolay Kalmarskiy
+[spoiler ЭТО делается так:-]

точно:
ORDER BY STA_1.OBJECT_MAIN desc, STA_1.STATEMENT_TYPE_ID desc, STA_1.STATEMENT_ID DESC
спасибо, полегчало
Nikolay Kalmarskiy
Дата: 27.11.2009 04:37:07
Журавлев Денис
ESM
Приводить на форуме номер счета клиента точно не следовало...

По поводу SORT (ORDER BY STOPKEY): если посмотрите на запрос внимательнее, вопрос ПОЧЕМУ отпадёт.
Уважаемый, я через целых 30 секунд понял на что Вы намекаете. Ох как мне тяжело.


Разделяю Ваше возмущение. Вряд ли Вам смог бы помочь человек, считающий для себя допустимым делать столь поспешные и столь неадекватные выводы, как те, что имеются в процитированном Вами сообщении.