DECLARE @StartTime datetime,@EndTime datetime
SELECT @StartTime=GETDATE()
select distinct born_on.name
from born_on,died_on
where (FLOOR(('2012-01-30'-born_on.DOB)/365.25) <= (
select max(FLOOR((died_on.DOD - born_on.DOB)/365.25))
from died_on, born_on
where (died_on.name=born_on.name))
)
and (born_on.name <> All(select name from died_on))
SELECT @EndTime=GETDATE()
SELECT DATEDIFF(ms,@StartTime,@EndTime) AS [Duration in millisecs]
我无法获取查询时间。相反,我收到以下错误:
sql:/home/an/Desktop/dbms/query.sql:9: ERROR: syntax error at or near "@"
LINE 1: DECLARE @StartTime datetime,@EndTime datetime
如果您指的是 psql,而不是您正在编写的某些程序,请使用
\?
获取帮助,并参阅:
\timing [on|off] toggle timing of commands (currently off)
然后你会得到如下输出:
# \timing on
Timing is on.
# select 1234;
?column?
----------
1234
(1 row)
Time: 0.203 ms
衡量执行时间的方法有很多种,每种方法都有优点和缺点。但无论你做什么,都会产生一定程度的“观察者效应”。即,测量本身可能会扭曲结果。 1.
EXPLAIN ANALYZE
EXPLAIN ANALYZE
SELECT DISTINCT born_on.name
FROM born_on b
WHERE date '2012-01-30' - b.dob <= (
SELECT max(d1.dod - b1.dob)
FROM born_on b1
JOIN died_on d1 USING (name) -- name must be unique!
)
AND NOT EXISTS (
SELECT FROM died_on d2
WHERE d2.name = b.name
);
使用热缓存执行几次以获得更多可比较的时间。有多个选项总执行时间
感兴趣,但请做到:
EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF)
大多数情况下,
TIMING
很重要 -
手册:
TIMING
在输出中包含实际启动时间和每个节点花费的时间。 重复读取系统时钟的开销会减慢 在某些系统上查询显着,因此设置此项可能很有用 当仅计算实际行数而不是精确时间时,将参数设置为FALSE
, 需要。始终测量整个语句的运行时间,甚至 当使用此选项关闭节点级计时时。 [...]
EXPLAIN ANALYZE
测量
在服务器上,使用服务器操作系统的服务器时间,不包括网络延迟。但是
EXPLAIN
也增加了一些开销来输出查询计划。2. psql 与 \timing
\timing
。
就像彼得演示的那样。说明书:
重要区别:\timing [ on | off ]
带参数,轮流显示每条SQL语句的长度 开启或关闭。如果没有参数,则在打开之间切换显示 然后关闭。显示单位为毫秒;间隔大于 1 第二个也以分钟:秒的格式显示,带有小时和天 如果需要添加字段。
psql 使用本地操作系统的本地时间在客户端测量,因此时间包括网络延迟。根据连接和返回数据量,这可能是一个可以忽略不计的差异或“巨大”。
3.启用log_duration
stdout
)。说明书:(
boolean
)
导致记录每个已完成语句的持续时间。这 默认为。只有超级用户才能更改此设置。off
对于使用扩展查询协议的客户端,解析的持续时间, 绑定和执行步骤独立记录。
还有log_min_duration_statement
4.使用
clock_timestamp()
进行精确的手动测量
说明书:
应该filiprem 提供了一种尽可能准确地获取临时查询执行时间的好方法。在现代硬件上,定时开销
可以忽略不计,但根据主机操作系统的不同,它可能会有很大差异。通过服务器应用程序找出答案 pg_test_timing
。
否则你可以像这样过滤开销:
DO
$do$
DECLARE
_timing1 timestamptz;
_start_ts timestamptz;
_end_ts timestamptz;
_overhead numeric; -- in ms
BEGIN
_timing1 := clock_timestamp();
_start_ts := clock_timestamp();
_end_ts := clock_timestamp();
-- take minimum duration as conservative estimate
_overhead := 1000 * extract(epoch FROM LEAST(_start_ts - _timing1
, _end_ts - _start_ts));
_start_ts := clock_timestamp();
PERFORM 1; -- your query here, replacing the outer SELECT with PERFORM
_end_ts := clock_timestamp();
-- RAISE NOTICE 'Timing overhead in ms = %', _overhead;
RAISE NOTICE 'Execution time in ms = %' , 1000 * (extract(epoch FROM _end_ts - _start_ts)) - _overhead;
END
$do$;
clock_timestamp()
几次应该可以预热它(如果这对您的操作系统很重要)。
测量有效负载查询的执行时间后,减去估计的开销以更接近实际时间。
当然,如果可以的话,对于廉价查询来说,循环 100000 次或在具有 100000 行的表上执行它更有意义,以使分散注意力的噪音变得微不足道。
PostgreSQL 不是 Transact-SQL。这是两个略有不同的事情。
DO $proc$
DECLARE
StartTime timestamptz;
EndTime timestamptz;
Delta double precision;
BEGIN
StartTime := clock_timestamp();
PERFORM foo FROM bar; /* Put your query here, replacing SELECT with PERFORM */
EndTime := clock_timestamp();
Delta := 1000 * ( extract(epoch from EndTime) - extract(epoch from StartTime) );
RAISE NOTICE 'Duration in millisecs=%', Delta;
END;
$proc$;
另一方面,测量查询时间不必这么复杂。还有更好的方法:
在
postgres命令行客户端\timing
可以在服务器日志中记录查询持续时间EXPLAIN
EXPLAIN (ANALYZE, BUFFERS) YOUR QUERY HERE;