Proc SQL в SAS работает в 37 раз медленнее, чем SQL в SQL Server - PullRequest
0 голосов
/ 23 октября 2019

У меня есть этот этап proc sql в SAS, который занимает около 1,7 с, однако, если я запускаю этот SQL через SQL-сервер или любой SQL-клиент, он занимает всего 0,04 с.

Из журнала Sastrace я обнаружил, что большую часть времени тратят на «Общее количество секунд выборки строк», что на самом деле не объясняет причину, по которой 3600% отличаются между SAS Proc SQL и SQL-клиентом.

Summary Statistics for ODBC are:
Total row fetch seconds were:                       1.736099
Total SQL execution seconds were:                   0.000698
Total SQL prepare seconds were:                     0.000168
Total SQL describe seconds were:                    0.003049
Total seconds used by the ODBC ACCESS engine were     1.743318

Что такое «Всего секунд выборки строк» ​​и как я могу улучшить время выполнения?

proc sql noprint;
    create table work.out1 as
    select a.search_key,
            a.field1,
            c.field2
    from db.tabl_1 as a
            join
                    db.tabl_2 as b
                    on a.search_key = b.search_key
                    and a.search_key in (&search_key)
            join
                    db.Tabl_3 as c
                    on b.field2 = c.field2
                    and upcase(XXX_field) EQ "XXX";
quit;
&search_key = 19709, 19710, 19711, 19712, .........

Редактировать: включить журнал сведений из sastrace

MPRINT(macro):   proc sql noprint;
SYMBOLGEN:  Macro variable SUBMISSION_STUDY_RUNS resolves to 
            19709, 19710, 19711, 19712, .........
MPRINT(macro):   create table work.out1 as select a.search_key, a.field1, c.field2 from db.tabl_1 as a join db.tabl_2 as b on 
a.search_key = b.search_key and a.search_key in 
(19709, 19710, 19711, 19712, .........) join db.Tabl_3 as c on b.field2 = c.field2 
and upcase(XXX_field) EQ "XXX";
SQLSRV: AUTOCOMMIT is NO for connection 11
SQLSRV: AUTOCOMMIT turned ON for connection id 11


SQLSRV_10181: Prepared: on connection 11
SELECT * FROM "db"."tabl_1"

SQLSRV: AUTOCOMMIT is NO for connection 12
SQLSRV: AUTOCOMMIT turned ON for connection id 12

SQLSRV_10182: Prepared: on connection 12
SELECT * FROM "db"."tabl_2"

SQLSRV: AUTOCOMMIT is NO for connection 13
SQLSRV: AUTOCOMMIT turned ON for connection id 13

SQLSRV_10183: Prepared: on connection 13
SELECT * FROM "db"."Tabl_3"

SQLSRV: AUTOCOMMIT is NO for connection 14
SQLSRV: AUTOCOMMIT turned ON for connection id 14

SQLSRV_10184: Prepared: on connection 14
 select a."search_key", a."field1", c."field2" from "db"."tabl_1" a inner join "db"."tabl_2" b on a."search_key" = b."search_key" inner join 
"db"."Tabl_3" c on b."field2" = c."field2" where ( a."search_key" in (19709, 19710, 19711, 19712, .........) ) and ({fn 
UCASE(c."XXX_field")} = 'XXX')

Запрос, который я выполнил в клиенте SQL:

select a.search_key,
a.field1,
c.field2
from db.tabl_1 as a
join
       db.tabl_2 as b
       on a.search_key = b.search_key
       and a.search_key in (19709, 19710, 19711, 19712, .........)
join
       db.Tabl_3 as c
       on b.field2 = c.field2
       and XXX_field = 'XXX';

Ответы [ 3 ]

2 голосов
/ 25 октября 2019

Поскольку вы использовали UPCASE () в одном запросе, а не в другом, вы фактически не выполняете тот же запрос. Удалите функцию UPCASE () из своего кода SAS.

2 голосов
/ 23 октября 2019

Это немного длинно для комментария.

Вы сравниваете две разные вещи - две совершенно разные базы данных. Предположительно, они работают на разных аппаратных средствах и в разных средах. Первое предположение состоит в том, что данные также отличаются.

Во-вторых, если вы хотите понять производительность, то вам нужно узнать о explain. К сожалению, это не поддерживаемая функция proc sql (хотя она доступна.

Учитывая ограниченную информацию, я бы предположил, что таблицы в SQL Server имеют соответствующие индексы, построенные на них, но таблиц в SAS нет. Вероятно, вы можете добавить соответствующие индексы и получить более близкие показатели производительности для двух систем. Однако это всего лишь предположение.

0 голосов
/ 25 октября 2019

Кажется, что когда SAS запускает proc sql, особенно join, он копирует всю таблицу в память SAS перед выполнением соединения / обработки. Тот же запрос на SQL-сервере просто соединит и вернет строки, которые соответствуют соединению.

Я заменил весь запрос на шаг данных SAS, и производительность теперь ближе к тому, что я получаю на SQL-сервере.

Пожалуйста, дайте мне знать, если у кого-то есть другая работа / объяснение

...