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

推荐答案

衡量执行时间的方法多种多样,各有利弊.但无论你做什么,observer effect的某些程度都适用.也就是说,测量本身可能会扭曲结果.

1. EXPLAIN ANALYZE

您可以预先输入EXPLAIN ANALYZE,它会报告整个查询计划,以及实际测量的估计成本时间.查询结果是actually executed(如果有副作用的话,还有所有副作用!).为SELECTINSERTUPDATEDELETE工作.

判断我对您的查询的修改版本是否实际上更快:

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
    );

使用热缓存执行几次以获得更多可比较的时间.Several options可用于调整细节级别.

虽然主要对total execution time感兴趣,但要做到:

EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF)

通常情况下,TIMING件事——the manual:件事

TIMING

在输出中包括实际启动时间和每个 node 花费的时间.

EXPLAIN ANALYZE使用服务器操作系统excluding network latency的服务器时间测量on the server.但是EXPLAIN也为输出查询计划增加了一些开销.

2. psql with \timing

或者在psql中使用\timing.Like Peter demonstrates.

The manual:

\timing [ on | off ]

通过一个参数,可以显示每条SQL语句的长度

Important difference: psql使用本地操作系统的本地时间测量on the client,因此时间为includes network latency.这可能是一个可以忽略不计的差异,也可能是huge,具体取决于连接和返回数据的量.

3. Enable log_duration

这可能是每次测量的开销最小,并且产生的计时失真最少.但这有点麻烦,因为你必须是超级用户,必须调整服务器配置,不能只针对单个查询的执行,还必须读取服务器日志(log)(除非重定向到stdout).

The manual:

log_duration (boolean)

导致记录每个已完成语句的持续时间.这个

对于使用扩展查询协议的客户端,解析的持续时间,

有一些相关的设置,比如log_min_duration_statement.

4. Precise manual measurement with clock_timestamp()

The manual:

clock_timestamp()返回实际的当前时间,因此即使在单个SQL命令中,其值也会发生变化.

filiprem provided a great way to get execution times for ad-hoc queries as exact as possible. On modern hardware, timing overhead should be insignificant but depending on the host OS it can vary wildly. Find out with the server application pg_test_timing.
Else you can mostly filter the overhead like this:

DO
$do$
DECLARE
   _timing1  timestamptz;
   _start_ts timestamptz;
   _end_ts   timestamptz;
   _overhead numeric;     -- in ms
   _timing   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$;

重复计算时间(此处使用3个时间戳进行最小值),并 Select 最小间隔作为定时开销的保守估计.此外,执行函数clock_timestamp()几次应该会使其预热(以防这对操作系统很重要).

在测量有效负载查询的执行时间后,减go 估计的开销以接近实际时间.

当然,对于便宜的查询来说,循环10万次或在一个有10万行的表上执行它(如果可以的话),让分散注意力的噪音变得无关紧要,这更有意义.

Sql相关问答推荐

如何查询未命名对象的SON数组

在Golang中管理数据库事务的简洁方法

在SQL中使用类别值将行转置为列

PostgreSQL:使用JSONB中的字段使用jsonb_to_Records()填充记录

如何在presto中映射id与名称

根据Rails活动记录中时间戳/日期时间的时间部分从PostgreSQL中提取记录

将JSON文件导入Postgres 16数据库时出错(22P04上次预期列之后的额外数据)

SQL按组 Select 最小值,当值不存在时为Null

在SQL中转换差异表的多列

连续天跟踪购买情况(将标记返回到另一列?)

snowflake中的动态文件名生成

获取所有用户的第一次和最后一次发货以及到达日期

按公司和产品查询最近发票的平均价格的SQL查询

将varchar (7)列转换为datetime

将有效数字作为 varchar 返回的 SQL 函数

我需要遍历权重值表并确定每个权重是否有效

如何在一个存储过程中创建全局临时表,并在另一个存储过程中使用它

为什么 Oracle 在一个查询中对同一张表同时执行 TABLE SCAN 和 INDEX UNIQUE SCAN?

如何在 SQL Server 中参数化 Select top 'n'

有条件求和