我正在使用Postgresql。我想测试一个函数执行的时间。由于该函数只需要几毫秒,我想在一个循环中调用它1000次,以获得准确的数字。
MySQL有一个BENCHMARK()函数来执行此操作。是否存在等价物,或者我是否必须编写带循环的过程来执行此操作?
答案 0 :(得分:3)
在PostgreSQL中,您通常使用generate_series
执行此操作:
SELECT my_function()
FROM generate_series(1,5000);
或
SELECT (SELECT my_query ....)
FROM generate_series(1,5000);
在后一种情况下,您可以将OFFSET 0
添加到子查询中或将其包装在STRICT
SQL函数中,以防止查询计划程序提取常见条件和子条款,以及其他方面都很聪明。
可以使用psql的\timing
命令,SET log_duration = on
或EXPLAIN (ANALYZE, BUFFERS)
来获取时间,所有这些都是微妙不同的东西 - 请参阅文档。简而言之,\timing
测量时间,包括往返和向客户转移价值。 log_duration
衡量服务器端执行时间。 EXPLAIN (ANALYZE, BUFFERS)
测量语句执行的详细信息但增加了时间开销,可能会使语句慢一点。
答案 1 :(得分:1)
用循环编写程序 - 不应超过5分钟。
答案 2 :(得分:-1)
CREATE OR REPLACE FUNCTION benchmark(loop_count int,
sql_expr text, -- SQL expression
is_cache_plan boolean default true) returns interval
immutable
strict
parallel safe -- Postgres 10 or later
language plpgsql
AS
$$
BEGIN
if is_cache_plan then
EXECUTE 'select ($1) from generate_series(1, $2)' using sql_expr, loop_count;
else
FOR i IN 1..loop_count LOOP
EXECUTE 'select ($1)' using sql_expr;
END LOOP;
end if;
RETURN clock_timestamp() - now();
END
$$;
-- TESTS (parse URL)
select benchmark(
500000,
$$substring(format('https://www.domain%s.com/?aaa=1111&b[2]=3#test', (random()*1000)::int::text) from '^[^:]+://([^/]+)')$$,
true);
-- 0 years 0 mons 0 days 0 hours 0 mins 0.300638 secs
select benchmark(
500000,
$$substring(format('https://www.domain%s.com/?aaa=1111&b[2]=3#test', (random()*1000)::int::text) from '^[^:]+://([^/]+)')$$,
false);
-- 0 years 0 mons 0 days 0 hours 0 mins 6.735336 secs
-- TESTS (generate UUID)
SELECT benchmark(1000000, $$uuid_in(overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing to_hex(floor(random()*(11-8+1) + 8)::int)::text from 17)::cstring)$$);
-- 0 years 0 mons 0 days 0 hours 0 mins 0.644648 secs
SELECT benchmark(1000000, $$md5(random()::text || clock_timestamp()::text)::uuid$$);
-- 0 years 0 mons 0 days 0 hours 0 mins 0.449026 secs
SELECT benchmark(1000000, $$gen_random_uuid()$$);
-- 0 years 0 mons 0 days 0 hours 0 mins 0.438084 secs