powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Переписать запрос (case)
7 сообщений из 7, страница 1 из 1
Переписать запрос (case)
    #39583625
CaseKiller
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вопрос тупой, но вдруг.
Тестовый пример:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
create table test_tab
as
select round(dbms_random.value(1, 100)) as f1,
       round(dbms_random.value(1, 100)) as f2,
       round(dbms_random.value(1, 100)) as f3,       
       round(dbms_random.value(1, 100)) as f4       
  from dual connect by level < 3000001;

create table test_tab2
as
select f1, f2, f3, f4 
      ,case when f1 = 1 then f3 else 0 end f5
      ,case when f1 between 2 and 3 then f3 else 0 end f6
      ,case when f1 between 4 and 6 then f3 else 0 end f7
      ,case when f1 between 7 and 9 then f3 else 0 end f8
      ,case when f1 between 10 and 12 then f3 else 0 end f9
      ,case when f1 between 7 and 12 then f3 else 0 end f10
      ,case when f1 > 12 then f3 else 0 end f11
      ,case when f2 < 4 then f3 else 0 end f12
      ,case when f2 = 2 then f3 else 0 end f13
      ,case when f2 = 4 then f3 else 0 end f14
      ,case when f2 > 4 then f3 else 0 end f15
      ,case when f2 between 5 and 7 then f3 else 0 end f16
      ,case when f2 between 8 and 10 then f3 else 0 end f17
      ,case when f2 between 11 and 13 then f3 else 0 end f18
      ,case when f2 between 8 and 13 then f3 else 0 end f19
      ,case when f2 > 13 then f3 else 0 end f20
      ,case when f2 between 14 and 37 then f3 else 0 end f21
      ,case when f2 between 13 and 24 then f3 else 0 end f22
      ,case when f2 between 25 and 36 then f3 else 0 end f33
      ,case when f2 > 36 then f4 else 0 end f34
      ,case when f2 between 3 and 4 then f3 else 0 end f35
      ,case when f1 = 2 then f4 else 0 end f36
      ,case when f1 between 3 and 4 then f4 else 0 end f37
      ,case when f1 between 5 and 7 then f4 else 0 end f38
      ,case when f1 between 8 and 10 then f4 else 0 end f39
      ,case when f1 between 11 and 13 then f4 else 0 end f40
      ,case when f1 between 8 and 13 then f4 else 0 end f41
      ,case when f1 > 13 then f4 else 0 end f42
      ,case when f2 <= 4 then f4 else 0 end f43
      ,case when f2 = 3 then f4 else 0 end f44
      ,case when f2 = 5 then f4 else 0 end f45
      ,case when f2 > 5 then f4 else 0 end f46
      ,case when f2 between 6 and 8 then f4 else 0 end f47
      ,case when f2 between 9 and 11 then f4 else 0 end f48
      ,case when f2 between 12 and 14 then f4 else 0 end f49
      ,case when f2 between 9 and 14 then f4 else 0 end f50
      ,case when f2 > 14 then f4 else 0 end f51
      ,case when f2 between 15 and 38 then f4 else 0 end f52
      ,case when f2 between 14 and 25 then f4 else 0 end f53
      ,case when f2 between 26 and 37 then f4 else 0 end f54
      ,case when f2 > 37 then f4 else 0 end f55
      ,case when f2 between 4 and 5 then f4 else 0 end f56
from test_tab;
-- рабает 10-12сек

-- пробуем без кейсов
drop table test_tab2;
create table test_tab
as
select f1, f2, f3, f4, 1 f5,1 f6,1 f7,1 f8,1 f9,1 f10,
       1 f11 ,1 f12,1 f13,1 f14,1 f15,1 f16,1 f17,1 f18,1 f19,1 f20
       ,1 f21,1 f22,1 f33,1 f34,1 f35,1 f36,1 f37,1 f38,1 f39,1 f40
       ,1 f41,1 f42,1 f43,1 f44,1 f45,1 f46,1 f47,1 f48,1 f49,1 f50,
       1 f51,1 f52,1 f53,1 f54,1 f55,1 f56
from test_tab;
-- работает 3сек

-- просто пробежимся
declare
  v number;
begin
  for c in (select * from test_table)
  loop
      v:=case when c.f1 = 1 then c.f3 else 0 end ;
      v:=case when c.f1 between 2 and 3 then c.f3 else 0 end ;
      v:=case when c.f1 between 4 and 6 then c.f3 else 0 end ;
      v:=case when c.f1 between 7 and 9 then c.f3 else 0 end ;
      v:=case when c.f1 between 10 and 12 then c.f3 else 0 end ;
      v:=case when c.f1 between 7 and 12 then c.f3 else 0 end ;
      v:=case when c.f1 > 12 then c.f3 else 0 end ;
      v:=case when c.f2 < 4 then c.f3 else 0 end ;
      v:=case when c.f2 = 2 then c.f3 else 0 end ;
      v:=case when c.f2 = 4 then c.f3 else 0 end ;
      v:=case when c.f2 > 4 then c.f3 else 0 end ;
      v:=case when c.f2 between 5 and 7 then c.f3 else 0 end ;
      v:=case when c.f2 between 8 and 10 then c.f3 else 0 end ;
      v:=case when c.f2 between 11 and 13 then c.f3 else 0 end ;
      v:=case when c.f2 between 8 and 13 then c.f3 else 0 end ;
      v:=case when c.f2 > 13 then c.f3 else 0 end ;
      v:=case when c.f2 between 14 and 37 then c.f3 else 0 end ;
      v:=case when c.f2 between 13 and 24 then c.f3 else 0 end ;
      v:=case when c.f2 between 25 and 36 then c.f3 else 0 end ;
      v:=case when c.f2 > 36 then c.f4 else 0 end ;
      v:=case when c.f2 between 3 and 4 then c.f3 else 0 end ;
      v:=case when c.f1 = 2 then c.f4 else 0 end ;
      v:=case when c.f1 between 3 and 4 then c.f4 else 0 end ;
      v:=case when c.f1 between 5 and 7 then c.f4 else 0 end ;
      v:=case when c.f1 between 8 and 10 then c.f4 else 0 end ;
      v:=case when c.f1 between 11 and 13 then c.f4 else 0 end ;
      v:=case when c.f1 between 8 and 13 then c.f4 else 0 end ;
      v:=case when c.f1 > 13 then c.f4 else 0 end ;
      v:=case when c.f2 <= 4 then c.f4 else 0 end ;
      v:=case when c.f2 = 3 then c.f4 else 0 end ;
      v:=case when c.f2 = 5 then c.f4 else 0 end ;
      v:=case when c.f2 > 5 then c.f4 else 0 end ;
      v:=case when c.f2 between 6 and 8 then c.f4 else 0 end ;
      v:=case when c.f2 between 9 and 11 then c.f4 else 0 end ;
      v:=case when c.f2 between 12 and 14 then c.f4 else 0 end ;
      v:=case when c.f2 between 9 and 14 then c.f4 else 0 end ;
      v:=case when c.f2 > 14 then c.f4 else 0 end ;
      v:=case when c.f2 between 15 and 38 then c.f4 else 0 end ;
      v:=case when c.f2 between 14 and 25 then c.f4 else 0 end ;
      v:=case when c.f2 between 26 and 37 then c.f4 else 0 end ;
      v:=case when c.f2 > 37 then c.f4 else 0 end;
      v:=case when c.f2 between 4 and 5 then c.f4 else 0 end ;
  end loop;  
end;
-- тоже 10сек



Самые простые кейсы увеличивают время запроса в 3 раза.
То есть по времени сделать все кейсы над одной строкой надо в два раза больше, чем прочитать и записать ее на диск.
То есть на примерно 150млн кейсов тратится 10сек., 15млн кейсов/сек, хотелось бы быстрее

Cам тупой вопрос: можно ли как-то ускорить данный кейс?
Что-то типа джоина с интервалами, но здесь они пересекаются, не подходит похоже.
...
Рейтинг: 0 / 0
Переписать запрос (case)
    #39583632
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
арифметические и логические операции, они же не бесплатные
это тоже работает медленнее просто запроса
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
CREATE TABLE test_tab2
AS
SELECT f1, f2, f3, f4, f1 f5,f1*f2 f6, f1 f7, f1-f3 f8, f1-f4 f9, f1+f4 f10,
       f1+1  f11, f1+1 f12, f1+1 f13, f1+12 f14, f1+18 f15,f3+29 f16, f1+1  f17,f2+5 f18,f1 f19,f1+55 f20
       ,f1+1 f21, f1+1 f22, f1+1 f33, f1+13 f34, f1+17 f35,f4+28 f36, f1+2  f37,f2+4 f38,f1 f39,f1+56 f40
       ,f1+1 f41, f1+1 f42, f1+1 f43, f1+14 f44, f1+16 f45,f1+27 f46, f1+f2 f47,f2+f4 f48,f1 f49,f1+57 f50,
       f1+1  f51, f1+1 f52, f1+2 f53, f1+15 f54, f1+15 f55,f2+26 f56
FROM test_tab
...
Рейтинг: 0 / 0
Переписать запрос (case)
    #39583637
CaseKiller
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymxарифметические и логические операции, они же не бесплатные
Непривычно, что здесь они стоят дороже, чем ввод/вывод, т.е. каких-то 50 кейсов медленнее, чем записать их результат на диск.
...
Рейтинг: 0 / 0
Переписать запрос (case)
    #39583640
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CaseKillerandreymxарифметические и логические операции, они же не бесплатные
Непривычно, что здесь они стоят дороже, чем ввод/вывод, т.е. каких-то 50 кейсов медленнее, чем записать их результат на диск.на форуме уже об этом говорили
лет 5-10 назад, точно не помню

а можем, и не раз
...
Рейтинг: 0 / 0
Переписать запрос (case)
    #39583731
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
CaseKillerНепривычно, что здесь они стоят дороже, чем ввод/вывод, т.е. каких-то 50 кейсов медленнее, чем записать их результат на диск.а где статистики выполнения? Не вижу распределения между IO, рекурсивными операциями и самими вычислениями case. И зачем такое усложнение с CTAS? Просто запрос было бы показательнее.

Кроме того, это:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
create table test_tab2
as
select f1, f2, f3, f4 
      ,case when f1 = 1 then f3 else 0 end f5
      ,case when f1 between 2 and 3 then f3 else 0 end f6
      ,case when f1 between 4 and 6 then f3 else 0 end f7
      ,case when f1 between 7 and 9 then f3 else 0 end f8
      ,case when f1 between 10 and 12 then f3 else 0 end f9
      ,case when f1 between 7 and 12 then f3 else 0 end f10
      ,case when f1 > 12 then f3 else 0 end f11
      ,case when f2 < 4 then f3 else 0 end f12
      ,case when f2 = 2 then f3 else 0 end f13
      ,case when f2 = 4 then f3 else 0 end f14
      ,case when f2 > 4 then f3 else 0 end f15
      ,case when f2 between 5 and 7 then f3 else 0 end f16
      ,case when f2 between 8 and 10 then f3 else 0 end f17
      ,case when f2 between 11 and 13 then f3 else 0 end f18
      ,case when f2 between 8 and 13 then f3 else 0 end f19
      ,case when f2 > 13 then f3 else 0 end f20
      ,case when f2 between 14 and 37 then f3 else 0 end f21
      ,case when f2 between 13 and 24 then f3 else 0 end f22
      ,case when f2 between 25 and 36 then f3 else 0 end f33
      ,case when f2 > 36 then f4 else 0 end f34
      ,case when f2 between 3 and 4 then f3 else 0 end f35
      ,case when f1 = 2 then f4 else 0 end f36
      ,case when f1 between 3 and 4 then f4 else 0 end f37
      ,case when f1 between 5 and 7 then f4 else 0 end f38
      ,case when f1 between 8 and 10 then f4 else 0 end f39
      ,case when f1 between 11 and 13 then f4 else 0 end f40
      ,case when f1 between 8 and 13 then f4 else 0 end f41
      ,case when f1 > 13 then f4 else 0 end f42
      ,case when f2 <= 4 then f4 else 0 end f43
      ,case when f2 = 3 then f4 else 0 end f44
      ,case when f2 = 5 then f4 else 0 end f45
      ,case when f2 > 5 then f4 else 0 end f46
      ,case when f2 between 6 and 8 then f4 else 0 end f47
      ,case when f2 between 9 and 11 then f4 else 0 end f48
      ,case when f2 between 12 and 14 then f4 else 0 end f49
      ,case when f2 between 9 and 14 then f4 else 0 end f50
      ,case when f2 > 14 then f4 else 0 end f51
      ,case when f2 between 15 and 38 then f4 else 0 end f52
      ,case when f2 between 14 and 25 then f4 else 0 end f53
      ,case when f2 between 26 and 37 then f4 else 0 end f54
      ,case when f2 > 37 then f4 else 0 end f55
      ,case when f2 between 4 and 5 then f4 else 0 end f56
from test_tab;

и это:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
create table test_tab
as
select f1, f2, f3, f4, 1 f5,1 f6,1 f7,1 f8,1 f9,1 f10,
       1 f11 ,1 f12,1 f13,1 f14,1 f15,1 f16,1 f17,1 f18,1 f19,1 f20
       ,1 f21,1 f22,1 f33,1 f34,1 f35,1 f36,1 f37,1 f38,1 f39,1 f40
       ,1 f41,1 f42,1 f43,1 f44,1 f45,1 f46,1 f47,1 f48,1 f49,1 f50,
       1 f51,1 f52,1 f53,1 f54,1 f55,1 f56
from test_tab;

будут разными: сравни длины типов их полей.
...
Рейтинг: 0 / 0
Переписать запрос (case)
    #39583735
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
xtenderбудут разными: сравни длины типов их полей.ошибся - перепутал... тут тупо number'ы будут
...
Рейтинг: 0 / 0
Переписать запрос (case)
    #39583850
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
create table t1 as
select round(dbms_random.value(1, 99)) f1,
       round(dbms_random.value(1, 99)) f2,
       round(dbms_random.value(1, 99)) f3,
       round(dbms_random.value(1, 99)) f4
  from dual
 connect by rownum < 800001;
  


Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
 select sum(f1), sum(f2), sum(f3), sum(f4)
  from t1

   SUM(F1)    SUM(F2)    SUM(F3)    SUM(F4)
---------- ---------- ---------- ----------
  39990803   40014270   39993670   39985506
1 row selected.
Elapsed: 00:00:00.09


SQL> select sum(f1*2), sum(f2*2), sum(f3*2), sum(f4*2)
  from t1

 SUM(F1*2)  SUM(F2*2)  SUM(F3*2)  SUM(F4*2)
---------- ---------- ---------- ----------
  79981606   80028540   79987340   79971012
1 row selected.
Elapsed: 00:00:00.18


SQL> select sum(f1*233333333.222222222222222222222222222), sum(f2*233333333.222222222222222222222222222), sum(f3*233333333.222222222222222222222222222), sum(f4*233333333.222222222222222222222222222)
  from t1

SUM(F1*233333333.222222222222222222222222222)
---------------------------------------------
SUM(F2*233333333.222222222222222222222222222)
---------------------------------------------
SUM(F3*233333333.222222222222222222222222222)
---------------------------------------------
SUM(F4*233333333.222222222222222222222222222)
---------------------------------------------
                                   9,3312E+15
                                   9,3367E+15
                                   9,3319E+15
                                   9,3300E+15
                                                                                
1 row selected.
Elapsed: 00:00:00.48
...
Рейтинг: 0 / 0
7 сообщений из 7, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Переписать запрос (case)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]