Author Archive

敏捷多模式匹配

Saturday, August 2nd, 2008

业务方一个需求, 要对一个表中某些文本字段进行多模式匹配, 找出含有某个关键词列表中关键词的记录. 为了实现这个需求, 搞了如下的SQL: select id, result from ( select /*+parallel(t 16)*/id, decode(sign(instr(x,'关键词1')),1,'关键词1,',null) || decode(sign(instr(x,'关键词2')),1,'关键词2,',null) || decode(sign(instr(x,'关键词3')),1,'关键词3,',null) as result from ( select id as id, col1||','||col2 as x from table1 ) t ) where result is not null / 说明一下: 1. 输出结果:  所有包含任意关键词的记录, 输出记录的id和该笔记录中所匹配到的关键词, 也可以根据需要输出其他字段.   2. 关键词列表: 把需要扫描的关键词都拼凑到SQL中, 而不是选择存放在一个表中去做表关联.  这样做是考虑到如果做表关联, instr这样的需求只能走nest loop, 而table1的记录有很大(百万级甚至更高).  而且关键词数量也不少, 一般是一两千个, 我这里为了便于阅读, 只写了三个.  这样的情况无论怎么样走nest loop, 逻辑读都非常大.   3. 关于并行: 需求紧急, 为了短平快的实现, 我用了并行.  也正好说说我对并行的理解.  并行, 其实是利用闲置的数据库服务器资源来换取任务执行的时间.  如果简单对一个10G级的大表进行全表扫描, 把并行开到32, 存储的吞吐一下子就到了极限.  而对于上面写的instr的SQL, 把并行度开到16, 则存储很闲, CPU里的user%一下子就到了96,7, 服务器load也到了很高的水平.  有一次不小心开了两个上面的SQL同时跑, 我有幸看到了三位数的load.  这样的工作不能在线上数据库做, 只能找一个空闲的非关键的环境来做.  付出这些代价, ...

大记录集驱动hash join导致额外物理读

Monday, May 26th, 2008

以前对hash join时应该用大记录集做驱动表还是用小记录集做驱动表一直存在疑虑, 直到最近做了一个实验, 才真正体会到其间的差别.实验过程如下. 用大记录集做驱动的执行计划如下: ——————————————————————————————————————————————————— | Id  | Operation              |  Name                | Rows  | Bytes |TempSpc| Cost  | ——————————————————————————————————————————————————— |   0 | SELECT STATEMENT       |                      |     1 |    12 |       |  1784 | |   1 |  SORT AGGREGATE        |                      |     1 |    12 |       |       | |*  2 |   HASH JOIN            |                      |  1820K|    20M|    31M|  ...

记一次BT的数据订正

Monday, May 26th, 2008

最近业务部门提出一个需求, 数据库里有些字段中保存的信息里全角和半角字符参杂, 影响市容, 要求做数据订正, 全部统一. 其中英文/数字/英文标点符号 都统一用半角字符, 而日文字符都统一用全角字符. 而且提出订正的字段中还包含一些clob字段.   那就函数+游标, 慢慢订正吧, 分析了一下, 要写四个函数: 1. varchar2数据类型的, 全角英文变半角. 2. clob数据类型的, 全角英文变半角. 3. varchar2数据类型的, 半角日文变全角. 4. clob数据类型的, 半角日文变全角.   开工: 第一个, 还好, 有现成函数: to_single_byte. TO_SINGLE_BYTE returns char with all of its multibyte characters converted to their corresponding single-byte characters. char can be of datatype CHAR, VARCHAR2, NCHAR, or NVARCHAR2. The value returned is ...

烦人的 “Recost for ORDER BY”

Friday, March 21st, 2008

起因是一个SQL走错了索引 SELECT ROWID AS rid FROM tab_1 s WHERE s.c_id = :1 ORDER BY s.gmt_r DESC 执行计划如下 ------------------------------------------------------------------------------------------ | Id  | Operation                                 |  Name                   | Rows| Bytes| Cost | ------------------------------------------------------------------------------------------ |   0 | SELECT STATEMENT                  |                             |   858| 25740| 138K| |* 1 |  TABLE ACCESS BY INDEX ROWID | tab_1                     |  858| 25740| 138K| |* 2 ...

UTF8字符集下如何做数据订正

Tuesday, February 26th, 2008

在utf8字符集的数据库中如何做数据订正.这个问题对我们DBA来说是比较现实的. 矛盾在于当数据库是UTF8时, 我们用Windows的操作系统如何input到数据库一个UTF8的文本. 经过多次的探索, 发现有三种方式. 1. 当Windows是简体中文操作系统时, 一个普通的txt文件(或者sql文件)都是ZHS16GBK格式的, 这个时候如果我们期望输入数据库的UTF8文本都是属于ZHS16GBK字符集时 (简单的说就是我们想输入简体中文或繁体中文时), 直接走SecureCRT 输入的中文都可以自动被转化为UTF8的格式. 与做普通字符集的数据订正没有区别. 2.当Windows是简体中文操作系统时, 如果我们期望输入数据库的UTF8文本不属于ZHS16GBK字符集时, 有两种方法把真正的UTF8字符输入给数据库 第一种: 把需要输入的文本保存为UTF8格式,  然后本机的NLS_LANG=AMERICAN_AMERICA.UTF8, 然后用SQLLDR到数据库中, 就可以了. 第二种: 把需要执行的SQL文件保存为UTF8格式, 然后SCP到对应的服务器上, 服务器的NLS_LANG=AMERICAN_AMERICA.UTF8, 然后在sqlplus里面用@操作符来调用这个SQL文件, 就可以了. 最后一种方法比较简便, 我举个例子说明一下: 'アイウエオ'这串字符是半角的日文, 不属于ZHS16GBK字符集. 那把如下的语句保存为名为test.sql的文件 select 'アイウエオ', dump('アイウエオ',1016) from dual; 文件保存的格式选择为utf8. 然后scp到服务器上. [admin@japan_db1 jonathan]$ env|grep NLS_L NLS_LANG=AMERICAN_AMERICA.UTF8 ops$admin@JAPAN>l 1* select 'アイウエオ', dump('アイウエオ',1016) from dual ops$admin@JAPAN>@test SP2-0042: unknown command "" - rest of line ignored. 'アイウエ��  DUMP('アイウエオ',1016)  アイウエオ  Typ=96 Len=15 CharacterSet=UTF8: ef,bd,b1,ef,bd,b2,ef,bd,b3,ef,bd,b4,ef,bd,b5  Elapsed: 00:00:00.00 ops$admin@JAPAN>spool off

组内分工

Wednesday, January 23rd, 2008

select  decode(username,  '大师',   '业界评论+吃喝玩乐',  '旺旺',   '前沿技术+时事评论',  'Donny',  '主机存储+旅行照片',  '陈立',   '技术,美女,漫画,各种片',  '老罗',   '加班以及加班的体会',  'SKY',    '阿里开发DBA第一牛',  '涛哥',   'oracle+mysql+postgresql+sqlserver+access+foxpro…',  '小强',   'oracle技术心得',  '勇斌', 'java+oracle',  'jacky',     '流水帐+育儿知识'  ) as 个人分工 from dual;