snippetsqlMajor
How can I benchmark a PostgreSQL query?
Viewed 0 times
postgresqlcanquerybenchmarkhow
Problem
I want to benchmark a query containing a user-defined function I have written for PostgreSQL. Are there any standard ways to run such a benchmark?
I know that timing can be turned on with
I know that timing can be turned on with
\timing at the psql prompt, but ideally I'd like to have a script that takes care of everything automatically: running the query a few times, clearing PostgreSQL cache after each run (probably by restarting the PostgreSQL's service), and outputting the average running time (and memory used is a plus).Solution
The widely used tool is the SQL command
Why would you want to clear the cache? The generally more likely use case is that the cache is populated. If you still want to go that route, here is a related answer on SO.
Not resetting the cache, here are two simple ways to test with many iterations:
Simple UDF
Or with random input - random numbers between 0 and 5000 in the example:
Or with a real life table:
More complex functions / queries
Call:
Careful: The query is actually executed!
Careful: Not fit for public use. Possible SQL injection.
Again, you can use random parameters if needed. Possibly with the
More options
For details, see:
EXPLAIN ANALYZE, possibly with more options for more details in the answer. That outputs the query plan with the planner estimates plus actual execution times.Why would you want to clear the cache? The generally more likely use case is that the cache is populated. If you still want to go that route, here is a related answer on SO.
Not resetting the cache, here are two simple ways to test with many iterations:
Simple UDF
EXPLAIN ANALYZE
SELECT f_myfunc(g) FROM generate_series (1,1000) AS t(g);Or with random input - random numbers between 0 and 5000 in the example:
EXPLAIN ANALYZE
SELECT f_myfunc((random()*5000)::int) FROM generate_series (1,1000) AS t(g);Or with a real life table:
EXPLAIN ANALYZE
SELECT f_myfunc(my_column) FROM my_tbl; -- LIMIT nMore complex functions / queries
CREATE FUNCTION f_test(ct int, sql text)
RETURNS void
LANGUAGE plpgsql AS
$func$
DECLARE
i int;
BEGIN
FOR i IN 1 .. $1 LOOP
EXECUTE sql; -- not safe against SQLi!
END LOOP;
END
$func$Call:
EXPLAIN ANALYZE
SELECT f_test(100, $q$SELECT * from MADLIB.gp('mock3', '{x1, x2, x3}', '{y1}', 100,20, 3)$q$Careful: The query is actually executed!
Careful: Not fit for public use. Possible SQL injection.
Again, you can use random parameters if needed. Possibly with the
USING clause of EXECUTE.More options
- psql
\timing
- the GUC
log_duration
- manual server-side timing with
clock_timestamp()
For details, see:
- Get execution time of PostgreSQL query
Code Snippets
EXPLAIN ANALYZE
SELECT f_myfunc(g) FROM generate_series (1,1000) AS t(g);EXPLAIN ANALYZE
SELECT f_myfunc((random()*5000)::int) FROM generate_series (1,1000) AS t(g);EXPLAIN ANALYZE
SELECT f_myfunc(my_column) FROM my_tbl; -- LIMIT nCREATE FUNCTION f_test(ct int, sql text)
RETURNS void
LANGUAGE plpgsql AS
$func$
DECLARE
i int;
BEGIN
FOR i IN 1 .. $1 LOOP
EXECUTE sql; -- not safe against SQLi!
END LOOP;
END
$func$EXPLAIN ANALYZE
SELECT f_test(100, $q$SELECT * from MADLIB.gp('mock3', '{x1, x2, x3}', '{y1}', 100,20, 3)$q$Context
StackExchange Database Administrators Q#42012, answer score: 38
Revisions (0)
No revisions yet.