Categories
日常应用

无知的比较:R和Teradata SQL(附赠TD经验几枚)

今年夏天的时候,刚刚开始被SQL虐,写了一篇很无知且更多是吐槽意味的blog post: 关于R的若干SQL等价问题。当时被若干朋友批评,我还浑然不觉个中精要。现在用Teradata也有半年多的时间了,越来越习惯了SQL的表述方式,也越来越体会到Teradata作为一个强大的数据仓库系统,是有多么的伟大...这感觉,就是只玩过几个G数据的乡下人进城,猛然看到各路英雄都是动辄几个T的数据,只能暂时以原来落后的思维方式、勉强挥舞着新型工具...好在个性不是特别愚钝,终究还是可以慢慢地领悟到T级数据的奥妙之处,终究用着新武器也越来越顺手了。

这一段时间,也充分证明了我是master in economics而绝对不是 in cs。数据库系统的原理终究学的不深——我哪儿知道MySQL的SQL和Teradata的SQL差了那么多呀...后来慢慢的去听同事传授TD使用经验,慢慢的去看老板传过来的代码,慢慢的一次次处理掉 no more spool space的错误和一次次接到SQL语句效率低强制退出的警告信之后,才逐渐地越来越了解TD的原理和脾气。工欲善其事,必先利其器,这些都是沉重的学费。

所以各位如果没有看过那篇「无知者无畏」状post的,就不要看了。直接接受我诚挚的道歉然后看下文吧。Teradata下简称TD。绝非专业知识,只是个人有限的了解,不对之处请及时批评。

有次跟同事聊,问他们为什么不在本机上装个TD测试用...然后被狠狠鄙视了一番——TD没有单机版!天生就是架在云上的。这东西还真是个原生的分布式数据仓库。

TD和oracle的关系也比较简单:一个是数据仓库,一个是数据库,功能设计什么的压根就不一样。这么说吧,oracle支撑的是ebay的网站运行,所以必然涉及大量的查询、插入、删除等请求。更麻烦的是,以ebay的访问量,这些请求都是同时过来的,这就要求系统并发性要好一点(专业人士可以绕道了,我只是浅薄的知道一点东西...)。体验过12306买火车票排队的大家,想必都知道这个系统并发起来的厉害。ebay若是也来个排队,消费者还不疯掉...

为了应对这样的任务,oracle的数据库设计自然是要按那「三大范式」来。这个就不多说了,再说就暴露了...

TD则是把oracle的数据定期地导出来存着,所以除了简单的复制数据之外,还要对数据进行一定程度的清理和整理,并不完全是最最原始的数据。然后到了食物链上端数据分析师手里,面对的数据很多都是已经弄的很整齐的了。说是食物链上端,只是因为这大概是分工中需要用到原始数据的最后一拨人,且这拨人用到的最多的就是查询(甚至是整表查询)和计算,所以我们写SQL的时候更多是考虑到这些需求,利用TD在这方面的性能优势——我已经很少在SAS或者R里面进行数据整理的工作了,性能跟TD完全不是一个量级的。

下面是TD使用的若干经验,不过这东西只有自己碰壁了才知道个中真滋味,我就是缩短一下解决问题的进程,不用太折腾到处搜来搜去。

No more spool space。当你的SQL没有语法错误,那么最常见的运行不下去的情况就是 no more spool space了,这大概是每个用TD的不管新鸟老鸟都会经历的痛苦历程。这个错误就像R里面报"cannot allocate a vector of size ***",或者你玩游戏正high的时候系统告诉你内存不足。解决的思路就是"空间换时间",就是看你具体怎么换了。

1. 多表join查询的时候,就要看这些表是怎么merge的——TD会去算是一大一小join,还是两个大表join。前者TD会复制小表到每个大表的"节点"上(大表肯定要分块存起来嘛),所以可以事先加collect statistics on *** column ***。后者就要费点脑子了,争取两个表的排序(PI)一致,这样TD join的时候就不需要对两个表都重新排列了是不是(merge join)?每一次重排都会占掉大量的临时空间呢。再者,查询结果储存到另外的永久或者临时表里面,就要注意primary index(简称PI)的选择,不要让TD再把查询结果重排...

2. 除了看primary index,有时候还要去注意partition by。有些已经建好的超级长的表需要去看是怎么真正"分块"存储的。对于partition by 的字段设定一个where条件,会让TD很快的知道你要查询和join的是哪些部分,大大缩短范围。一般说来,最常见的partition by就是时间了,缩短一个时间范围也不失为良策嘛。

3. 擅用cast()可以避免很多跟数据类型有关的错误,这个就不赘述了。

4. No space on ***说明没有永久表的存储空间了,这个就得去删过于古老的表和去要新的空间了。

5. 每段SQL不要太长,join不宜太多。熟悉TD的脾气之后,就张弛有度了,擅用临时表。

6. 多用group by少用distinct。

7. 最后终极野蛮办法,如果实在是没法两个大表join又没有partition by的话...手动按PI拆其中某个表吧。

----例行碎碎念----
那些在LinkedIn上endorse我R的朋友们,我真心感觉承受不起呀!至今依旧觉得我的R很烂,代码只停留在"可运行"的水平,效率大都很糟糕,基本就是折磨CPU的...哎,非科班出身终究是有莫大的差距呀。

Categories
网站建设

301,永久重定向!

我这次彻底被惹火了。真的大感慨:早知如此,何必当初!

落园两个域名、两个服务器分别独立运行的痛苦日子终于要结束了——我也痛下决心,牺牲一部分速度,做出这个抉择——落园国内服务器暂停。接下来的问题就是把.cn的域名做一个301永久重定向,全部指到loyhome.com来。

其实本来是想做一个在MySQL 层面的数据库同步的,但无奈两个服务器之间不给力,同步很难做。wordpress镜像的次选择就是直接在配置文件里面写入远程MySQL服务器地址,但也不是很给力。最后的办法就是全静态同步,自然还是不给力。我实在忍无可忍了,再也不想忍受两个站点手动同步刷新的痛苦,于是决定赶紧的搞定这个事儿。.com转到国内还牵扯一个备案问题,同样是折磨的我实在是受不了的事儿。索性,一了百了,全面转身.com并使用国外的服务器。为了清理这一年来的旧账(两边都有留言),我还写了一天的R代码来一一对应各种文章ID和留言ID,最后终于全面整理了过来。国内的服务器可能还会保留给后花园用。

我不得不唠叨一下这些痛苦的历史。落园从2006年开始运行在独立域名上(落园以前是在blogcn上的,前段时间blogcn删档,落园最早的文章就全部覆灭了,正好,毁尸灭迹,不怕有人追踪什么了),以loyhome.cn作为唯一的域名。后来波折一再,.cn域名从来就没有消停过。先是备案,由于换空间商换了一次,所以前后备案痛苦的备了两次;后是实名认证,直接导致去年不在国内的我无奈的看着域名被封了两个月,这也是当时一怒之下注册loyhome.com取而代之的缘故。这还是域名和空间的事儿。落园所依赖的程序上,本来采用的是Textcube,后来实在是不给力就转到wordpress了。当年那次大搬家费了我好大事儿,不得不手动对应两个MySQL数据库,写了一堆PHP程序来实现了完全的迁移。至于各种小波折小调整就不罗列了……

回顾这差不多7年的落园成长史,就是一部充斥着各种折磨的辛酸血泪史。不堪忍受删文章,就自己掏钱买域名买空间做独立博客;不堪忍受TC的低效,就自己写PHP代码鼓捣MySQL彻底转到Wordpress来;不堪忍受一而再、再而三的实名认证,就忍痛把旧域名转到新域名来。谁说写博客容易的?我真不想骂人,可是哪有强迫人不仅要有文笔、还要有独立思考能力、还要有时间有持之以恒精神、还要不计金钱报酬(落园从未也永远不会挂任何广告)、还要学会写PHP代码查bug弄SEO、还要搞的定国外的域名注册……说真的,落园能走到现在,我已经很满足了,很满足了。有的时候真的想过放弃算了,一个博客而已。但是还是跌跌撞撞的坚持下来了。现在所有人都在微博上玩的不亦乐乎,还有多少人关注博客?在大多数博客沦落为相互复制粘贴、挂满小广告或者半年不更新的今日,还有多少人关注什么原创和持之以恒?

总而言之,当我在阿里巴巴商学院门口看到马云题写的四个有点难看的字“永不放弃”的时候,当时想到落园就有种泪流满面的冲动。如果没有这么多朋友的支持与鼓励、没有一篇篇日志后面那些温馨的让人忘记寒冬的留言,我可能真的坚持不到今天。还有,当我不止一次在网上搜问题搜回到自己的博客的时候,只有会心一笑,稍稍讽刺,却也暗自欢喜。

我很对不起很多国内的、尤其是限制国外流量的教育网的朋友们。我知道这一次301之后,很多人访问落园的速度会慢下来,还有可能打不开。但是,我已经没有其他更好的办法了。如果IPV6可以用的话,还请用Google reader订阅落园的RSS吧!如果你们连留言页面都打不开,那么就给我发邮件吧!我不想失去大家的关怀,也请大家不要忘记落园这么一个越来越孤独的存在。

丢车,是为了保帅。只有暗自的期望落园的未来可以顺畅的走下去,毕竟一个博客的核心是内容——正如301对应的解释,永久重定向,我也不想浪费更多的时间在其他的网站管理等琐事上了。涅磐之后,还请雨过天晴。