postgresql中position函数的性能详解
起因:
postgresql中position函数提供从头查返回第⼀个匹配到字符串的下标。
⽽我需要返回从后向前查第⼀个匹配到的坐标,但是postgressql并未提供相关函数,所以⾃⼰写了如下代码提供相关功能:
CREATE OR REPLACE FUNCTION lastindexof(text, character)
RETURNS integer AS
$BODY$
begin
if $1 is null then return NULL;
end if;
for i in reverse length($1) .. 1
loop
if substr($1,i,1) = $2
then
return i;
end if;
end loop;
return NULL;
end
$BODY$
LANGUAGE plpgsql IMMUTABLE STRICT
本来以为事情完美解决,但是性能的差距却让⼈感觉很失望,如下图
数据库原⽣的“position”和⾃⼰提供“lastindexof”,居然产⽣了30倍以上的性能差距,那么探究缘由就变成⼀个有意思的事情。也算第⼀次尝试翻阅数据库源码,中间总是有点⼩⿇烦,不过当我到如下代码的时候,那种恍然⼤悟的欣喜也算满⾜了⾃⼰求知欲。
注意看1054⾏,运⽤了指针~ 可见数据库底层运算,⽤了引⽤传递,⽽我⾃⼰写的函数是⼀个拷贝传递。
原因到了,解决问题也就⼿到擒来,拿C写⼀个扩展?或者?
本可以拿C写⼀些底层代码练练⼿,不过那⼜需要重新编译等等,时间有限,留给以后去做吧,先想个简单的办法去解决它。解决⽅法如下
select length(dir) -position('/' in reverse(dir)) +1 from log_hup_ftp_30
测试性能截图字符串函数详解
好吧,虽然由于函数的复杂性增加,性能还是慢了⼀倍多,但是⽐起之前5s之久还是快了不少。
tips:
最近得到德哥的回答,引⽤传递可以使⽤游标类型!再次谢谢德哥~
补充: SQL之查询函数LOCATE、POSITION、INSTR、FIND_IN_SET、IN、LIKE
LOCATE()
返回要查询的字符串在被查询字符串⾥第⼀次出现的位置
注:当在 MySQL 4.0 中时,如有任⼀参数是⼀个⼆进制字符串,它才是字母⼤⼩写敏感的
LOCATE(substr,str)
返回substr字符串在str⾥第⼀次出现的位置,没有返回0
SELECT LOCATE('.',t.str)FROM `table` t;
>5
LOCATE(substr,str,pos)
返回substr字符串在str⾥pos(起始位置)出现的位置,没有返回0
注:pos必须⼤于第⼀次出现的位置,才能显⽰第⼆次出现的位置
SELECT LOCATE('.',t.str,6)FROM `table` t;
>9//当⼩于等于第⼀次出现的位置(5)时,返回的还是第⼀次出现的位置
POSITION()
返回要查询的字符串在被查询字符串⾥第⼀次出现的位置(和locate⽤法⼀样,查了很多资料position是locate的别名)POSITION(substr IN str)
返回substr字符串在str出现的位置,没有返回0
SELECT POSITION('cn' IN t.str)FROM `table` t;
>10
INSTR()
返回要查询的字符串在被查询字符串⾥第⼀次出现的位置。这和LOCATE()的双参数形式相同,只是参数的顺序被颠倒。INSTR(str,substr)
返回substr字符串在str出现的位置,没有返回0
SELECT INSTR(t.str,'com')FROM `table` t;
>6
FIND_IN_SET()
返回在集合中的索引位置(竖向发展)
FIND_IN_SET(str,strlist)
返回str1在strlist集合中的索引位置
SELECT FIND_IN_SET('demo',t.str) FROM `table` t;
>1//返回索引
IN()
返回在集合中的索引位置(同FIND_IN_SET)
str IN (strlist)
返回str1在strlist集合中的索引位置
SELECT 'demo' IN(t.str) FROM `table` t;
>1//返回索引
LIKE
返回类似(模糊)字符的集合
LIKE %str%
返回以str类似的集合
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。如有错误或未考虑完全的地⽅,望不吝赐教。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。