Postgres相当于MySQL的BENCHMARK()函数

时间:2012-10-20 08:23:32

标签: mysql performance postgresql database-performance postgresql-performance

我正在使用Postgresql。我想测试一个函数执行的时间。由于该函数只需要几毫秒,我想在一个循环中调用它1000次,以获得准确的数字。

MySQL有一个BENCHMARK()函数来执行此操作。是否存在等价物,或者我是否必须编写带循环的过程来执行此操作?

3 个答案:

答案 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 = onEXPLAIN (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