當(dāng)前位置:首頁(yè) >  站長(zhǎng) >  數(shù)據(jù)庫(kù) >  正文

postgresql 中position函數(shù)的性能詳解

 2021-05-03 16:02  來(lái)源: 腳本之家   我來(lái)投稿 撤稿糾錯(cuò)

  域名預(yù)訂/競(jìng)價(jià),好“米”不錯(cuò)過(guò)

這篇文章主要介紹了postgresql 中position函數(shù)的性能詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧。

起因:

postgresql中position函數(shù)提供從頭查找返回第一個(gè)匹配到字符串的下標(biāo)。

而我需要返回從后向前查找第一個(gè)匹配到的坐標(biāo),但是postgressql并未提供相關(guān)函數(shù),所以自己寫(xiě)了如下代碼提供相關(guān)功能:

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

 

本來(lái)以為事情完美解決,但是性能的差距卻讓人感覺(jué)很失望,如下圖

數(shù)據(jù)庫(kù)原生的“position”和自己提供“lastindexof”,居然產(chǎn)生了30倍以上的性能差距,那么探究緣由就變成一個(gè)有意思的事情。也算第一次嘗試翻閱數(shù)據(jù)庫(kù)源碼,中間總是有點(diǎn)小麻煩,不過(guò)當(dāng)我找到如下代碼的時(shí)候,那種恍然大悟的欣喜也算滿足了自己求知欲。

注意看1054行,運(yùn)用了指針~ 可見(jiàn)數(shù)據(jù)庫(kù)底層運(yùn)算,用了引用傳遞,而我自己寫(xiě)的函數(shù)是一個(gè)拷貝傳遞。

原因找到了,解決問(wèn)題也就手到擒來(lái),拿C寫(xiě)一個(gè)擴(kuò)展?或者?

本可以拿C寫(xiě)一些底層代碼練練手,不過(guò)那又需要重新編譯等等,時(shí)間有限,留給以后去做吧,先想個(gè)簡(jiǎn)單的辦法去解決它。

解決方法如下

1select length(dir) -position('/' in reverse(dir)) +1 from log_hup_ftp_30

測(cè)試性能截圖

好吧,雖然由于函數(shù)的復(fù)雜性增加,性能還是慢了一倍多,但是比起之前5s之久還是快了不少。

tips:

最近得到德哥的回答,引用傳遞可以使用游標(biāo)類型!再次謝謝德哥~

補(bǔ)充: SQL之查詢函數(shù)LOCATE、POSITION、INSTR、FIND_IN_SET、IN、LIKE

LOCATE()返回要查詢的字符串在被查詢字符串里第一次出現(xiàn)的位置

注:當(dāng)在 MySQL 4.0 中時(shí),如有任一參數(shù)是一個(gè)二進(jìn)制字符串,它才是字母大小寫(xiě)敏感的

LOCATE(substr,str)返回substr字符串在str里第一次出現(xiàn)的位置,沒(méi)有返回0

SELECT LOCATE('.',t.str)FROM `table`

t;>5

LOCATE(substr,str,pos)返回substr字符串在str里pos(起始位置)出現(xiàn)的位置,沒(méi)有返回0

注:pos必須大于第一次出現(xiàn)的位置,才能顯示第二次出現(xiàn)的位置

SELECT LOCATE('.',t.str,6)FROM `table` t;>9//當(dāng)小于等于第一次出現(xiàn)的位置(5)時(shí),返回的還是第一次出現(xiàn)的位置

POSITION()返回要查詢的字符串在被查詢字符串里第一次出現(xiàn)的位置(和locate用法一樣,查了很多資料position是locate的別名)

POSITION(substr IN str)返回substr字符串在str出現(xiàn)的位置,沒(méi)有返回0

SELECT POSITION('cn' IN t.str)FROM `table` t;>10

INSTR()返回要查詢的字符串在被查詢字符串里第一次出現(xiàn)的位置。這和LOCATE()的雙參數(shù)形式相同,只是參數(shù)的順序被顛倒。

INSTR(str,substr)返回substr字符串在str出現(xiàn)的位置,沒(méi)有返回0

SELECT FIND_IN_SET('demo.com.cn',t.str) FROM `table` t;
>1//返回索引

 

FIND_IN_SET()返回在集合中的索引位置(豎向發(fā)展)

FIND_IN_SET(str,strlist)返回str1在strlist集合中的索引位置

SELECT 'demo.com.cn' IN(t.str) FROM `table` t;
>1//返回索引

 

IN()返回在集合中的索引位置(同F(xiàn)IND_IN_SET)

str IN (strlist)返回str1在strlist集合中的索引位置

SELECT 'demo.com.cn' IN(t.str) FROM `table` t;
>1//返回索引

LIKE返回類似(模糊)字符的集合

LIKE %str%返回以str類似的集合

文章來(lái)源:腳本之家

來(lái)源地址:https://www.jb51.net/article/205181.htm

申請(qǐng)創(chuàng)業(yè)報(bào)道,分享創(chuàng)業(yè)好點(diǎn)子。點(diǎn)擊此處,共同探討創(chuàng)業(yè)新機(jī)遇!

相關(guān)文章

熱門排行

信息推薦