Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Сравнение СУБД [игнор отключен] [закрыт для гостей] / PostgreSQL/Oracle на конкретном запросе. Почему так? / 14 сообщений из 14, страница 1 из 1
21.04.2009, 22:11
    #35945650
web_fox
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
Здравствуйте. Вопрос, наверное, больше к специалистам по 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
21.04.2009, 22:18
    #35945657
web_fox
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
Файл данных для PG.
...
Рейтинг: 0 / 0
21.04.2009, 22:18
    #35945658
web_fox
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
Файл данных ORA.
...
Рейтинг: 0 / 0
22.04.2009, 05:38
    #35945840
ЯЕХХ
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
Оператор "<" в Постгресе не может использоваться для MERGE JOIN.
50 миллионов итераций в NESTED LOOP естественно тормозят.

Скорее всего поможет только переписывание запроса, в данном примере заменить группировку на подзапрос. В Оракле это тоже значительное ускорение даст.
...
Рейтинг: 0 / 0
22.04.2009, 11:28
    #35946387
LeXa NalBat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
можно изменить запрос, тогда он будет выполняться на постгресе гораздо быстрее
...
Рейтинг: 0 / 0
22.04.2009, 12:27
    #35946676
softwarer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
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
22.04.2009, 13:03
    #35946795
ОКТОГЕН
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
softwarer, c PostgreSQL прецеденты были)))))
...
Рейтинг: 0 / 0
22.04.2009, 13:13
    #35946823
ОКТОГЕН
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
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
22.04.2009, 13:14
    #35946834
ОКТОГЕН
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
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
22.04.2009, 16:37
    #35947653
web_fox
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
PostgreSQL/Oracle на конкретном запросе. Почему так?
Спасибо за ответы. В данном случае интересует больше не сама возможность ускорить данный запрос, а конкретная причина его медленного выполнения на PG. Как я понял, это из-за авторОператор "<" в Постгресе не может использоваться для MERGE JOIN

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

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


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