在 PostgreSQL 中提取拆分字符串的最后一部分的最有效方法是啥?
Posted
技术标签:
【中文标题】在 PostgreSQL 中提取拆分字符串的最后一部分的最有效方法是啥?【英文标题】:What is the most efficient way to extract the last part of a split string in PostgreSQL?在 PostgreSQL 中提取拆分字符串的最后一部分的最有效方法是什么? 【发布时间】:2020-10-13 14:11:02 【问题描述】:我想在 PostgreSQL 函数中将完全限定域的子域提取到第二级。
目前我有以下可用的 sn-p,但我不确定这是否是最有效的方法:
subdomains := left(query, length(query) - length(tld));
RETURN reverse(split_part(reverse(subdomains), '.', 1)) || tld;
保证query
以tld
子字符串结尾。
例子:
+---------------------+---------+---------------+
| query | tld | output |
+---------------------+---------+---------------+
| abc.example.com | .com | example.com |
| x.y.z.example.co.uk | .co.uk | example.co.uk |
| zzz.123.yyy.com.br | .com.br | yyy.com.br |
+---------------------+---------+---------------+
【问题讨论】:
【参考方案1】:这个效率也不是特别高,但至少没有两次reverse
,我猜array_length
很便宜,string_to_array
大致和split_part
一样贵。这可能是错误的,但值得一试。
sd_arr := string_to_array(subdomains, '.');
RETURN sd_arr[array_length(sd_arr , 1)] || tld;
没有变量赋值会更好:
RETURN (select arr[array_length(arr,1)] from (select string_to_array(subdomains, '.') as arr) t) || tld;
【讨论】:
有趣的是,与此同时,我几乎自己创建了完全相同的替代方案,它具有性能优势,但不幸的是不到 1% :(【参考方案2】:不确定这是否更有效,但您可以将其与您的实现进行比较:
create or replace function get_domain(p_input text, p_tld text)
returns text
as
$$
declare
l_tld text[];
l_items text[];
begin
l_tld := string_to_array(trim('.' from p_tld), '.');
l_items := string_to_array(trim('.' from p_input), '.');
return array_to_string(l_items[cardinality(l_items) - cardinality(l_tld):], '.');
end
$$
language plpgsql
immutable;
它本质上将输入和***域转换为数组(剥离任何前导 .
以避免空数组元素。
然后它通过从输入的长度中减去 tld 的长度(=元素的数量)来计算要返回的起始元素。因此,对于输入 x.y.z.example.co.uk
,这是 6 - 2,这意味着它返回从第 4 个元素开始的所有内容,然后将其转换回“点”表示法。
Online example
【讨论】:
以上是关于在 PostgreSQL 中提取拆分字符串的最后一部分的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章