具有max()性能的SQLite SELECT

时间:2015-09-08 08:37:36

标签: performance sqlite

我有一张约150万行和3列的表格。专栏'时间戳'是REAL类型和索引。我通过PHP PDO访问SQLite数据库。

以下三个选项在不到一毫秒的时间内运行:

select timestamp from trades
select timestamp + 1 from trades
select max(timestamp) from trades

以下选择需要将近半秒钟:

select max(timestamp) + 1 from trades

为什么?

编辑: Lasse要求提供一个"解释查询计划",我已经在PHP PDO查询中运行了这个,因为我目前没有直接的SQLite3命令行工具访问权限。我想这没关系,结果如下:

explain query plan select max(timestamp) + 1 from trades:
    [selectid] => 0
    [order] => 0
    [from] => 0
    [detail] => SCAN TABLE trades (~1000000 rows)

explain query plan select max(timestamp) from trades:
    [selectid] => 0
    [order] => 0
    [from] => 0
    [detail] => SEARCH TABLE trades USING COVERING INDEX tradesTimestampIdx (~1 rows)

1 个答案:

答案 0 :(得分:4)

此查询的原因

select max(timestamp) + 1 from trades

需要很长时间,查询引擎必须为每个记录计算MAX值,然后向其中添加一个值。计算MAX值涉及进行全表扫描,并且必须为每条记录重复此操作,因为您要为该值添加一个。

在查询中

select timestamp + 1 from trades

正在对每条记录进行计算,但引擎只需扫描整个表一次。并在此查询中

select max(timestamp) from trades

引擎 必须扫描整个表格,但它也只扫描一次。

来自SQLite documentation

  

包含单个MIN()或MAX()聚合函数的查询,其参数是索引的最左列可能通过执行单个索引查找而不是通过扫描整个表

我从文档中强调可能,因为对于SELECT MAX(x)+1 FROM table形式的查询,可能需要进行全表扫描 如果列x不是索引的最左列。