Можно ли ускорить выборку

Андрей_C2
Дата: 09.03.2007 06:49:00
Есть функция, в которой отрабатывает следующая выборка
select * from t_in t1 where t1.acc_num
not in
(
select scr.acc_num accnum
from t_tr tr, t_in scr
where tr.tr_acc_subnum = scr.acc_subnum
and
tr.tr_acc_num = scr.acc_num
and
tr.tr_src_pay_time > to_date(Pi_from_date)
union
select to_char(car_id)
from c_ext car, t_car_in scr
where car.user_data = scr.acc_subnum
)

Соответственно, если в t_in данных, то отрабатывает довольно долго.
Можно ли переписать чтоб побыстрее стало ?
Прошу строго не судить! :)
SeaGate
Дата: 09.03.2007 06:55:50
Андрей_C2

Можно ли переписать чтоб побыстрее стало ?

План где?
Q u a d r o
Дата: 09.03.2007 06:57:34
План? DDL для таблиц/индексов и DML для занесения тестовых данных?

P.S. Внутри not in - union не нужен.
Андрей_C2
Дата: 09.03.2007 07:05:44
Q u a d r o

P.S. Внутри not in - union не нужен.

А как же я без него? :)
Q u a d r o
Дата: 09.03.2007 07:07:58
Андрей_C2
Q u a d r o

P.S. Внутри not in - union не нужен.

А как же я без него? :)

union all, он не требует сортировки.
Просто спросил, ежели чего...
Дата: 09.03.2007 07:15:25
Q u a d r o
Андрей_C2
Q u a d r o

P.S. Внутри not in - union не нужен.

А как же я без него? :)

union all, он не требует сортировки.
А разве [NOT] IN-подзапрос не выпоняет невный DISTINCT и связанную с ним же неявную сортировку???
Q u a d r o
Дата: 09.03.2007 07:22:31
Просто спросил, ежели чего...
А разве [NOT] IN-подзапрос не выпоняет невный DISTINCT и связанную с ним же неявную сортировку???


Нет.

SQL> select *
  2   from dual
  3   where dummy not in (
  4    select 'a' from dual
  5    union all
  6    select 'b' from dual
  7   );

Execution Plan
----------------------------------------------------------
Plan hash value: 317371734

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     2 |     6   (0)| 00:00:01 |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
|   3 |   UNION-ALL        |      |       |       |            |          |
|*  4 |    FILTER          |      |       |       |            |          |
|   5 |     FAST DUAL      |      |     1 |       |     2   (0)| 00:00:01 |
|*  6 |    FILTER          |      |       |       |            |          |
|   7 |     FAST DUAL      |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------

SQL> select *
  2   from dual
  3   where dummy not in (
  4    select 'a' from dual
  5    union
  6    select 'b' from dual
  7   );

Execution Plan
----------------------------------------------------------
Plan hash value: 1478444540

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |     1 |     2 |     8  (25)| 00:00:01 |
|*  1 |  FILTER            |      |       |       |            |          |
|   2 |   TABLE ACCESS FULL| DUAL |     1 |     2 |     2   (0)| 00:00:01 |
|   3 |   SORT UNIQUE      |      |     2 |       |     6  (67)| 00:00:01 |
|   4 |    UNION-ALL       |      |       |       |            |          |
|*  5 |     FILTER         |      |       |       |            |          |
|   6 |      FAST DUAL     |      |     1 |       |     2   (0)| 00:00:01 |
|*  7 |     FILTER         |      |       |       |            |          |
|   8 |      FAST DUAL     |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------

distinct идёт, например, когда оптимизатор переписывает in как join, но делать этого он не обязан.
Q u a d r o
Дата: 09.03.2007 07:41:36
Q u a d r o
distinct идёт, например, когда оптимизатор переписывает in как join, но делать этого он не обязан.

btw, distinct не нужен в случае semi-join'ов.
Андрей_C2
Дата: 09.03.2007 07:49:43
select * from t_car_querry_in t1 where t1.acc_num
        not in
         (
           select scr.acc_num accnum
             from t_transaction tr, t_car_querry_in scr
                 where tr.tr_acc_subnum = scr.acc_subnum 
                   and
                       tr.tr_acc_num = scr.acc_num 
                   and
                       tr.tr_src_pay_time > to_date('08.03.2007') 
                   and
                       tr.tr_from_conn = 6
           union all
           select to_char(car.user_data.In_crd_id)
             from carem_ext.create_table car, t_car_querry_in scr
                 where car.user_data.In_Cheque = scr.acc_subnum 
                   and
                       car.user_data.In_Crd_Id = scr.acc_num
          )

SELECT STATEMENT, GOAL = ALL_ROWS			Cost=5729	Cardinality=291	Bytes=7275
 FILTER					
  TABLE ACCESS FULL	Object owner=ERKC	Object name=T_CAR_QUERRY_IN	Cost=2	Cardinality=292	Bytes=7300
  UNION-ALL					
   TABLE ACCESS BY INDEX ROWID	Object owner=ERKC	Object name=T_TRANSACTION	Cost=11	Cardinality=1	Bytes=16
    NESTED LOOPS			Cost=13	Cardinality=1	Bytes=33
     TABLE ACCESS FULL	Object owner=ERKC	Object name=T_CAR_QUERRY_IN	Cost=2	Cardinality=1	Bytes=17
     INDEX RANGE SCAN	Object owner=ERKC	Object name=AK_PAY_TIME	Cost=3	Cardinality=10	
   HASH JOIN			Cost=26	Cardinality=171	Bytes=27189
    TABLE ACCESS FULL	Object owner=CAREM_EXT	Object name=CREATE_TABLE	Cost=24	Cardinality=50	Bytes=7100
    TABLE ACCESS FULL	Object owner=ERKC	Object name=T_CAR_QUERRY_IN	Cost=2	Cardinality=292	Bytes=4964


select * from t_car_querry_in t1 where t1.acc_num
        not in
         (
           select scr.acc_num accnum
             from t_transaction tr, t_car_querry_in scr
                 where tr.tr_acc_subnum = scr.acc_subnum 
                   and
                       tr.tr_acc_num = scr.acc_num 
                   and
                       tr.tr_src_pay_time > to_date('08.03.2007') 
                   and
                       tr.tr_from_conn = 6
           union 
           select to_char(car.user_data.In_crd_id)
             from carem_ext.create_table car, t_car_querry_in scr
                 where car.user_data.In_Cheque = scr.acc_subnum 
                   and
                       car.user_data.In_Crd_Id = scr.acc_num
          )

SELECT STATEMENT, GOAL = ALL_ROWS			Cost=6023	Cardinality=291	Bytes=7275
 FILTER					
  TABLE ACCESS FULL	Object owner=ERKC	Object name=T_CAR_QUERRY_IN	Cost=2	Cardinality=292	Bytes=7300
  SORT UNIQUE			Cost=41	Cardinality=102	Bytes=16092
   UNION-ALL					
    TABLE ACCESS BY INDEX ROWID	Object owner=ERKC	Object name=T_TRANSACTION	Cost=11	Cardinality=1	Bytes=16
     NESTED LOOPS			Cost=13	Cardinality=1	Bytes=33
      TABLE ACCESS FULL	Object owner=ERKC	Object name=T_CAR_QUERRY_IN	Cost=2	Cardinality=1	Bytes=17
      INDEX RANGE SCAN	Object owner=ERKC	Object name=AK_PAY_TIME	Cost=3	Cardinality=10	
    HASH JOIN			Cost=26	Cardinality=101	Bytes=16059
     TABLE ACCESS FULL	Object owner=CAREM_EXT	Object name=CREATE_TABLE	Cost=24	Cardinality=84	Bytes=11928
     TABLE ACCESS FULL	Object owner=ERKC	Object name=T_CAR_QUERRY_IN	Cost=2	Cardinality=292	Bytes=4964


Помогло, еще вариант ? :)
Q u a d r o
Дата: 09.03.2007 08:08:45
давайте на время забудем про

select to_char(car.user_data.In_crd_id)
             from carem_ext.create_table car, t_car_querry_in scr
                 where car.user_data.In_Cheque = scr.acc_subnum 
                   and
                       car.user_data.In_Crd_Id = scr.acc_num

Зачем вам здесь два раза иди в t_car_querry_in?

select *
	from t_car_querry_in t1
	where t1.acc_num not in
         (
           select scr.acc_num accnum
             from t_transaction tr, t_car_querry_in scr
                 where tr.tr_acc_subnum = scr.acc_subnum 
                   and tr.tr_acc_num = scr.acc_num 
                   and tr.tr_src_pay_time > to_date('08.03.2007') 
                   and tr.tr_from_conn = 6
		);

Что происходит, если это переписать как

select *
	from t_car_querry_in t1
	where t1.acc_num not in
         (
           select tr.tr_acc_num
             from t_transaction tr
                 where tr.tr_acc_subnum = t1.acc_subnum 
                   and tr.tr_acc_num = t1.acc_num 
                   and tr.tr_src_pay_time > to_date('08.03.2007') 
                   and tr.tr_from_conn = 6
		)

?