powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / PostgreSQL/Oracle на конкретном запросе. Почему так?
14 сообщений из 14, страница 1 из 1
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35945650
web_fox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте. Вопрос, наверное, больше к специалистам по PostgreSQL.

Обьясните, пожалуйста, почему нижеследующий запрос выполняется на Oracle 10g 40 сек, а на PostgreSQL 8.3 - 1:30 сек. Железо одинаковое. В чём может быть проблема на PG?

Таблица PG:
CREATE TABLE "public"."space_acc" (
"dat" TIMESTAMP WITHOUT TIME ZONE NOT NULL,
"gbytes" NUMERIC NOT NULL,
CONSTRAINT "space_acc_pkey" PRIMARY KEY("dat")
) WITHOUT OIDS;

Идентичная таблица Oracle:
create table
(
DAT DATE not null,
GBYTES NUMBER not null
);
alter table add primary key (DAT) using index;

Заполнение таблицы Oracle:
Код: plaintext
1.
2.
3.
4.
INSERT INTO space_acc
    SELECT SYSDATE - round( 10000  /  2 ) + rownum +  0 . 5  * dbms_random.VALUE() AS dat,
           round( 500  +  10  * rownum +  20  * dbms_random.VALUE()) AS GBytes
      FROM (SELECT * FROM dual CONNECT BY  1  =  1 )
     WHERE rownum <  10000 
Потом экспортим эти же данные в PG.

ЗАПРОС для замера времени (у меня на PG = 1:30 сек):
Код: plaintext
1.
2.
3.
4.
5.
SELECT space_acc.dat AS d_begin,
       MIN(space_acc1.dat) AS d_end,
       space_acc.gbytes AS s_begin
  FROM space_acc
  JOIN space_acc space_acc1 ON space_acc.dat < space_acc1.dat
 GROUP BY space_acc.dat, space_acc.gbytes;

План Oracle:
Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT STATEMENT, GOAL = ALL_ROWS		 1036 	 4999000 	 154969000 
 HASH GROUP BY					 1036 	 4999000 	 154969000 
  MERGE JOIN					 173 	 4999000 	 154969000 
   SORT JOIN					 78 	 9999 	 219978 
    TABLE ACCESS FULL	SCOTT	SPACE_ACC	 8 	 9999 	 219978 
   SORT JOIN					 10 	 9999 	 89991 
    INDEX FAST FULL SCAN SCOTT	SYS_C005859	 8 	 9999 	 89991 

План PG:
Код: plaintext
1.
2.
3.
4.
5.
HashAggregate  (cost= 1252858 . 35 .. 1252983 . 34  rows= 9999  width= 24 ) (actual time= 137284 . 280 .. 137291 . 990  rows= 9998  loops= 1 )
  ->  Nested Loop  (cost= 0 . 00 .. 1002908 . 35  rows= 33326667  width= 24 ) (actual time= 0 . 068 .. 69450 . 834  rows= 49985001  loops= 1 )
        ->  Seq Scan on space_acc  (cost= 0 . 00 .. 162 . 99  rows= 9999  width= 16 ) (actual time= 0 . 020 .. 5 . 259  rows= 9999  loops= 1 )
        ->  Index Scan using space_acc_pkey on space_acc space_acc1  (cost= 0 . 00 .. 58 . 62  rows= 3333  width= 8 ) (actual time= 0 . 014 .. 3 . 568  rows= 4999  loops= 9999 )
              Index Cond: (space_acc.dat < space_acc1.dat)
Total runtime:  137294 . 569  ms
Вакуум сделан.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35945657
web_fox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Файл данных для PG.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35945658
web_fox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Файл данных ORA.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35945840
ЯЕХХ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Оператор "<" в Постгресе не может использоваться для MERGE JOIN.
50 миллионов итераций в NESTED LOOP естественно тормозят.

Скорее всего поможет только переписывание запроса, в данном примере заменить группировку на подзапрос. В Оракле это тоже значительное ускорение даст.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35946387
LeXa NalBat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно изменить запрос, тогда он будет выполняться на постгресе гораздо быстрее
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35946676
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
web_foxОбьясните, пожалуйста, почему нижеследующий запрос выполняется на Oracle 10g 40 сек, а на PostgreSQL 8.3 - 1:30 сек. Железо одинаковое. В чём может быть проблема на PG?
Основная проблема совершенно точно не в PG. Посмотрите, пожалуйста, внимательно:

Код: plaintext
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.
Connected to Oracle Database 10g Enterprise Edition Release  10 . 1 . 0 . 5 . 0  
Connected as test

SQL> create table space_acc
   2   (
   3   DAT DATE not null,
   4   GBYTES NUMBER not null
   5   );

Table created

SQL> alter table space_acc add primary key (DAT) using index;

Table altered

SQL> INSERT INTO space_acc
   2       SELECT SYSDATE - round( 10000  /  2 ) + rownum +  0 . 5  * dbms_random.VALUE() AS dat,
   3              round( 500  +  10  * rownum +  20  * dbms_random.VALUE()) AS GBytes
   4         FROM (SELECT * FROM dual CONNECT BY  1  =  1 )
   5        WHERE rownum <  10000 
   6   ;

 9999  rows inserted

SQL> exec dbms_stats.gather_schema_stats (ownname => user);

PL/SQL procedure successfully completed

SQL> set serveroutput on;
SQL> 
SQL> declare
   2     type record_result is record (d_begin date, d_end date, s_begin number);
   3     type record_list is table of record_result;
   4     type record_cur is ref cursor return record_result;
   5     cr record_cur;
   6     r record_list;
   7     t1 timestamp;
   8   begin
   9     -- Мой вариант
  10     t1 := systimestamp;
  11     open cr for select
  12                 s.dat d_begin,
  13                 lead (s.dat) over (order by s.dat) d_end,
  14                 s.gbytes s_begin
  15                 from
  16                 space_acc s;
  17     fetch cr bulk collect into r;
  18     close cr;
  19     dbms_output.put_line ('Мой вариант: ' || (systimestamp - t1));
  20     -- Ваш вариант
  21     t1 := systimestamp;
  22     open cr for SELECT space_acc.dat AS d_begin,
  23                  MIN(space_acc1.dat) AS d_end,
  24                  space_acc.gbytes AS s_begin
  25                  FROM space_acc
  26                  JOIN space_acc space_acc1 ON space_acc.dat < space_acc1.dat
  27                  GROUP BY space_acc.dat, space_acc.gbytes;
  28     fetch cr bulk collect into r;
  29     close cr;
  30     dbms_output.put_line ('Ваш вариант: ' || (systimestamp - t1));
  31   end;
  32   /

Мой вариант: + 000000000   00 : 00 : 00 . 047000000 
Ваш вариант: + 000000000   00 : 01 : 13 . 313000000 

PL/SQL procedure successfully completed

Полагаю, когда лёгким движением руки запрос может быть ускорен с семидесяти секунд до пятидесяти тысячных долей секунды - рассуждать о сравнении серверов немного неуместно. Вообще, фраза "сорок секунд на десяти тысячах записей" должна звучать похоронным колоколом.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35946795
ОКТОГЕН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer, c PostgreSQL прецеденты были)))))
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35946823
ОКТОГЕН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer, план для вашего варианта в Постгре
запрос (выполнился за 47 милисекунд)
Код: plaintext
1.
2.
3.
4.
5.
6.
select
 s.dat d_begin,
 lead (s.dat) over (order by s.dat) d_end,
 s.gbytes s_begin
from
space_acc s
план
Код: plaintext
1.
2.
WindowAgg  (cost= 0 . 00 .. 569 . 77  rows= 9999  width= 16 )
  ->  Index Scan using space_acc_pkey on space_acc s  (cost= 0 . 00 .. 419 . 78  rows= 9999  width= 16 )
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35946834
ОКТОГЕН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
web_fox, ваш запрос выполнился за 46 секунд

Код: plaintext
1.
2.
3.
4.
5.
SELECT space_acc.dat AS d_begin,
MIN(space_acc1.dat) AS d_end,
 space_acc.gbytes AS s_begin
  FROM space_acc
   JOIN space_acc space_acc1 ON space_acc.dat < space_acc1.dat
        GROUP BY space_acc.dat, space_acc.gbytes;
план
Код: plaintext
1.
2.
3.
4.
HashAggregate  (cost= 1252858 . 35 .. 1252983 . 34  rows= 9999  width= 24 )
  ->  Nested Loop  (cost= 0 . 00 .. 1002908 . 35  rows= 33326667  width= 24 )
        ->  Seq Scan on space_acc  (cost= 0 . 00 .. 162 . 99  rows= 9999  width= 16 )
        ->  Index Scan using space_acc_pkey on space_acc space_acc1  (cost= 0 . 00 .. 58 . 62  rows= 3333  width= 8 )
              Index Cond: (space_acc.dat < space_acc1.dat)
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35947653
web_fox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо за ответы. В данном случае интересует больше не сама возможность ускорить данный запрос, а конкретная причина его медленного выполнения на PG. Как я понял, это из-за авторОператор "<" в Постгресе не может использоваться для MERGE JOIN

Где можно прочитать остальные особенности работы PG именно при выполнении/построении планов запросов? Если в сравнении с Oracle, то вообще идеально. В PG новичёк.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35948124
ОКТОГЕН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
web_fox, а какое у вас железо? Меня просто интересует почему мой результат 47 секунд,
а не 70? Версия PostgreSQL 8.4. Это они так его оптимизировали, или это разница в железе?
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35948402
web_fox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ОКТОГЕН, я всё запускал на домашнем компе: двухядерный AMD 4000+, WinXPSP3.
PG 8.3.7 = 90 сек
PG 8.4 = 90 сек
планы одинаковые.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35948404
web_fox
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ОКТОГЕН,

обе версии PG во время выполнения использовали одно ядро, т.е. 50%.
...
Рейтинг: 0 / 0
PostgreSQL/Oracle на конкретном запросе. Почему так?
    #35948454
ОКТОГЕН
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
web_fox, рискну предположить, что запросы, на которых планировщик особенно "проседает" есть в любой СУБД. Это данность, зависящая от реализации каждой конкретной СУБД. В постгрессовские
исходники не заглядывал.
А может стоит задачка написать особенно тормозной проект?)))
Их есть у меня)) Надо в опциях задать, например, запрет на сканирование индекса.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / PostgreSQL/Oracle на конкретном запросе. Почему так?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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