测量执行 PostgreSQL 查询所需的时间
Measure the time it takes to execute a PostgreSQL query
基于Measure the time it takes to execute a t-sql query,如何在 PostgreSQL 中多次尝试查询?
大纲是
-- 设置试验次数(比如 1000)
SELECT CURRENT_DATE ; -- save start time
BEGIN
LOOP
-- execute query to be tested
END LOOP;
END;
SELECT CURRENT_DATE ; -- save end time
I.E.我想要一个 PostgreSQL 等效于以下 TSQL 代码,取自 HumbleWebDev 从链接的 TSQL 问题的回答:请参阅 [代码参考]
声明@tTOTAL int = 0
声明 @i 整数 = 0
声明@itrs integer = 100
while @i < @itrs
begin
declare @t0 datetime = GETDATE()
--your query here
declare @t1 datetime = GETDATE()
set @tTotal = @tTotal + DATEDIFF(MICROSECOND,@t0,@t1)
set @i = @i + 1
end
select @tTotal/@itrs
-- 您的查询在这里:标准 SQL 查询,例如 Select * from table1 inner -- join table2,或执行存储过程等
我自己有 MSSQL 背景,现在更经常在 Postgres 工作,我感受到了你的痛苦 =)
Postgres 的“问题”在于它仅支持 'basic' SQL 命令(SELECT、INSERT、UPDATE、CREATE、ALTER 等...)你想添加逻辑(IF THEN、WHILE、变量等)你需要切换到 pl/pgsql ,你只能在函数内部使用(AFAIK)。从 TSQL POV 来看,有很多限制,事实上,有些事情突然不再起作用(或者需要以不同的方式完成。例如 SELECT * INTO TEMPORARY TABLE tempTable FROM someTable
不起作用,但 CREATE TABLE tempTable AS SELECT * FROM someTable
将)
我也通过艰难的方式学到的东西是 CURRENT_TIMESTAMP
(或 Now()
)将 return 在交易中具有相同的价值。由于函数内的所有内容都在事务内运行,这意味着您必须使用 clock_timstamp()
无论如何,为了回答你的问题,我认为这应该让你继续:
CREATE OR REPLACE FUNCTION fn_test ( nbrOfIterations int)
RETURNS TABLE (iterations int, totalTime interval, secondsPerIteration int)
AS $$
DECLARE
i int;
startTime TIMESTAMP;
endTime TIMESTAMP;
dummy text;
BEGIN
i := 1;
startTime := clock_timestamp();
WHILE ( i <= nbrOfIterations) LOOP
-- your query here
-- (note: make sure to not return anything or you'll get an error)
-- example:
SELECT pg_sleep INTO dummy FROM pg_sleep(1);
i := i + 1;
END LOOP;
endTime := clock_timestamp();
iterations := nbrOfIterations;
totalTime := (endTime - startTime);
secondsPerIteration := (EXTRACT(EPOCH FROM endTime) - EXTRACT(EPOCH FROM startTime)) / iterations;
RETURN NEXT;
END;
$$ language plpgsql;
SELECT * FROM fn_test(5);
虽然接受的答案是正确的,但这种调整对我来说效果更好。再次,我想强调下面这个额外的答案是基于上面的答案,没有它是不可能的。使用我在下面所做的调整在我自己的情况下效果更好。
下面的答案确实几乎完全基于公认的答案。但是,我更改了 return 的使用方式,并将秒更改为毫秒:
----------------------------------------------------------------------------------------------------
-- fn__myFunction_Q.sql
----------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
-- DROP FUNCTION mySchema.fn__myFunction
--------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION mySchema.fn__myFunction ( nbrOfIterations int)
RETURNS TABLE (iterations int, totalTime interval, millisecondsPerIteration int) -- interval --
AS $$
declare
i int;
startTime TIMESTAMP;
endTime TIMESTAMP;
-- dummy text;
iterations int;
millisecondsPerIteration int;
totalTime interval;
BEGIN
i := 1;
startTime := clock_timestamp();
WHILE ( i <= nbrOfIterations) LOOP
PERFORM /* Put your query here, replacing SELECT with PERFORM */
--------------------------------------------------------------------------------------------
--SELECT
-- YOUR QUERY HERE
-- ...
--------------------------------------------------------------------------------------------
i := i + 1; -- very important to increment loop counter, else one gets an infinite loop!!!
END LOOP;
endTime := clock_timestamp();
iterations := nbrOfIterations;
totalTime := (endTime - startTime);
millisecondsPerIteration := 1000 * (EXTRACT(EPOCH FROM endTime) - EXTRACT(EPOCH FROM startTime)) / iterations;
RETURN QUERY select iterations, totalTime, millisecondsPerIteration;
-- RETURNS TABLE (iterations int, totalTime interval, secondsPerIteration int) -- interval --
-- RETURN NEXT;
END;
$$ language plpgsql;
--------------------------------------------------------------------------------------------
要调用此函数,只需使用:
SELECT * from mySchema.fn__myFunction(1000) as ourTableResult;
基于Measure the time it takes to execute a t-sql query,如何在 PostgreSQL 中多次尝试查询?
大纲是 -- 设置试验次数(比如 1000)
SELECT CURRENT_DATE ; -- save start time
BEGIN
LOOP
-- execute query to be tested
END LOOP;
END;
SELECT CURRENT_DATE ; -- save end time
I.E.我想要一个 PostgreSQL 等效于以下 TSQL 代码,取自 HumbleWebDev 从链接的 TSQL 问题的回答:请参阅 [代码参考] 声明@tTOTAL int = 0 声明 @i 整数 = 0 声明@itrs integer = 100
while @i < @itrs
begin
declare @t0 datetime = GETDATE()
--your query here
declare @t1 datetime = GETDATE()
set @tTotal = @tTotal + DATEDIFF(MICROSECOND,@t0,@t1)
set @i = @i + 1
end
select @tTotal/@itrs
-- 您的查询在这里:标准 SQL 查询,例如 Select * from table1 inner -- join table2,或执行存储过程等
我自己有 MSSQL 背景,现在更经常在 Postgres 工作,我感受到了你的痛苦 =)
Postgres 的“问题”在于它仅支持 'basic' SQL 命令(SELECT、INSERT、UPDATE、CREATE、ALTER 等...)你想添加逻辑(IF THEN、WHILE、变量等)你需要切换到 pl/pgsql ,你只能在函数内部使用(AFAIK)。从 TSQL POV 来看,有很多限制,事实上,有些事情突然不再起作用(或者需要以不同的方式完成。例如 SELECT * INTO TEMPORARY TABLE tempTable FROM someTable
不起作用,但 CREATE TABLE tempTable AS SELECT * FROM someTable
将)
我也通过艰难的方式学到的东西是 CURRENT_TIMESTAMP
(或 Now()
)将 return 在交易中具有相同的价值。由于函数内的所有内容都在事务内运行,这意味着您必须使用 clock_timstamp()
无论如何,为了回答你的问题,我认为这应该让你继续:
CREATE OR REPLACE FUNCTION fn_test ( nbrOfIterations int)
RETURNS TABLE (iterations int, totalTime interval, secondsPerIteration int)
AS $$
DECLARE
i int;
startTime TIMESTAMP;
endTime TIMESTAMP;
dummy text;
BEGIN
i := 1;
startTime := clock_timestamp();
WHILE ( i <= nbrOfIterations) LOOP
-- your query here
-- (note: make sure to not return anything or you'll get an error)
-- example:
SELECT pg_sleep INTO dummy FROM pg_sleep(1);
i := i + 1;
END LOOP;
endTime := clock_timestamp();
iterations := nbrOfIterations;
totalTime := (endTime - startTime);
secondsPerIteration := (EXTRACT(EPOCH FROM endTime) - EXTRACT(EPOCH FROM startTime)) / iterations;
RETURN NEXT;
END;
$$ language plpgsql;
SELECT * FROM fn_test(5);
虽然接受的答案是正确的,但这种调整对我来说效果更好。再次,我想强调下面这个额外的答案是基于上面的答案,没有它是不可能的。使用我在下面所做的调整在我自己的情况下效果更好。
下面的答案确实几乎完全基于公认的答案。但是,我更改了 return 的使用方式,并将秒更改为毫秒:
----------------------------------------------------------------------------------------------------
-- fn__myFunction_Q.sql
----------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------
-- DROP FUNCTION mySchema.fn__myFunction
--------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION mySchema.fn__myFunction ( nbrOfIterations int)
RETURNS TABLE (iterations int, totalTime interval, millisecondsPerIteration int) -- interval --
AS $$
declare
i int;
startTime TIMESTAMP;
endTime TIMESTAMP;
-- dummy text;
iterations int;
millisecondsPerIteration int;
totalTime interval;
BEGIN
i := 1;
startTime := clock_timestamp();
WHILE ( i <= nbrOfIterations) LOOP
PERFORM /* Put your query here, replacing SELECT with PERFORM */
--------------------------------------------------------------------------------------------
--SELECT
-- YOUR QUERY HERE
-- ...
--------------------------------------------------------------------------------------------
i := i + 1; -- very important to increment loop counter, else one gets an infinite loop!!!
END LOOP;
endTime := clock_timestamp();
iterations := nbrOfIterations;
totalTime := (endTime - startTime);
millisecondsPerIteration := 1000 * (EXTRACT(EPOCH FROM endTime) - EXTRACT(EPOCH FROM startTime)) / iterations;
RETURN QUERY select iterations, totalTime, millisecondsPerIteration;
-- RETURNS TABLE (iterations int, totalTime interval, secondsPerIteration int) -- interval --
-- RETURN NEXT;
END;
$$ language plpgsql;
--------------------------------------------------------------------------------------------
要调用此函数,只需使用:
SELECT * from mySchema.fn__myFunction(1000) as ourTableResult;