libname output '/data/files/jeff' %let DateStart = '01Jan2013'd; %let DateEnd = '01Jun2013'd; proc sql; CREATE TABLE output.id AS ( SELECT DISTINCT id FROM mydb.sale_volume AS sv WHERE sv.category IN ('a','b','c') AND sv.trans_date BETWEEN &DateStart AND &DateEnd ) CREATE TABLE output.sums AS ( SELECT id,SUM(sales) FROM mydb.sale_volue AS sv INNER JOIN output.id AS ids ON ids.id = sv.id WHERE sv.trans_date BETWEEN &DateStart AND &DateEnd GROUP BY id ) run;
目标是根据类别成员资格在表中查询某些id.然后,我将这些成员的活动汇总到所有类别.
>运行第一个查询以获取子集
>运行第二个查询,对每个ID求和
>运行内部连接两个结果集的第三个查询.
如果我理解正确,确保我的所有代码都完全通过而不是交叉加载可能更有效.
在昨天发布一个问题之后,一位成员建议我可以通过提出一个更具体针对我的情况的单独的绩效问题而受益.
我正在使用SAS Enterprise Guide编写一些程序/数据查询.我没有权限修改存储在“Teradata”中的基础数据.
我的基本问题是在这种环境中编写高效的SQL查询.例如,我为一小部分ID查询一个大表(有数千万条记录).然后,我使用此子集再次查询更大的表:
proc sql; CREATE TABLE subset AS ( SELECT id FROM bigTable WHERE someValue = x AND date BETWEEN a AND b )
这可以在几秒钟内完成,并返回90k ID.接下来,我想在大表中查询这组ID,然后出现问题.我希望随着时间的推移对ID的值进行求和:
proc sql; CREATE TABLE subset_data AS ( SELECT bigTable.id,SUM(bigTable.value) AS total FROM bigTable INNER JOIN subset ON subset.id = bigTable.id WHERE bigTable.date BETWEEN a AND b GROUP BY bigTable.id )
无论出于何种原因,这需要很长时间.区别在于第一个查询标记’someValue’.第二个是查看所有活动,不管’someValue’中的内容是什么.例如,我可以标记每个订购披萨的顾客.然后我会查看订购披萨的所有客户的每次购买.
我对SAS并不太熟悉,所以我正在寻找有关如何更有效地做到这一点或加快速度的任何建议.我对任何想法或建议持开放态度,如果我能提供更多细节,请告诉我.我想我很惊讶第二个查询需要很长时间来处理.
解决方法
SAS处理为您翻译的事情,但这可能令人困惑.例如,我见过用VARCHAR(400)列定义的“懒惰”数据库表,其值永远不会超过一些较小的长度(如人名的列).在数据库中,这不是什么大问题,但由于SAS没有VARCHAR数据类型,因此每行创建一个宽度为400个字符的变量.即使使用数据集压缩,这也可能会使得到的SAS数据集不必要地变大.
另一种方法是使用“显式传递”,使用相关DBMS的实际语法编写本机查询.这些查询完全在DBMS上执行,并将结果返回给SAS(它仍然为您进行数据类型转换.例如,这是一个“传递”查询,它执行两个表的连接并创建一个SAS数据集作为结果:
proc sql; connect to teradata (user=userid password=password mode=teradata); create table mydata as select * from connection to teradata ( select a.customer_id,a.customer_name,b.last_payment_date,b.last_payment_amt from base.customers a join base.invoices b on a.customer_id=b.customer_id where b.bill_month = date '2013-07-01' and b.paid_flag = 'N' ); quit;
请注意,括号内的所有内容都是本机Teradata sql,并且连接操作本身在数据库中运行.
您在问题中显示的示例代码不是SAS / Teradata程序的完整工作示例.为了更好地提供帮助,您需要显示真实的程序,包括任何库引用.例如,假设您的真实程序如下所示:
proc sql; CREATE TABLE subset_data AS SELECT bigTable.id,SUM(bigTable.value) AS total FROM TDATA.bigTable bigTable JOIN TDATA.subset subset ON subset.id = bigTable.id WHERE bigTable.date BETWEEN a AND b GROUP BY bigTable.id ;
这将指示先前分配的LIBNAME语句,SAS通过该语句连接到Teradata.如果SAS甚至能够将完整查询传递给Teradata,那么该WHERE子句的语法将非常相关. (您的示例未显示“a”和“b”所指的内容.SAS可以执行连接的唯一方法是将两个表拖回本地工作会话并在SAS服务器上执行连接.
我强烈建议的一件事是,您试图说服您的Teradata管理员允许您在某个实用程序数据库中创建“驱动程序”表.我们的想法是,您将在Teradata中创建一个包含要提取的ID的相对较小的表,然后使用该表执行显式连接.我相信你需要更正式的数据库培训才能做到这一点(比如如何定义一个合适的索引以及如何“收集统计数据”),但凭借这些知识和能力,你的工作才会飞翔.
我可以继续,但我会在这里停下来.我每天都广泛使用SAS和Teradata,而我所说的是这个星球上最大的Teradata环境之一.我喜欢两种编程.