SQL 查询优化
SQL queries optimization
我在优化某些考虑了日期时间字段的 sql 查询时遇到问题。
首先,我的table结构如下:
CREATE TABLE info (
id int NOT NULL auto_increment,
name varchar(20),
infoId int,
shortInfoId int,
text varchar(255),
token varchar(60),
created_at DATETIME,
PRIMARY KEY(id)
KEY(created_at));
在对一些简单查询使用解释后,我添加了 created_at 键,这提高了我大部分简单查询的性能。我现在遇到以下查询的问题:
SELECT min(created_at), max(created_at) from info order by id DESC limit 10000
通过此查询,我想获得最后 10k 个结果之间的时间跨度。
使用 explain 后得到以下结果:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE info ALL NULL NULL NULL NULL 4 NULL
关于如何提高此查询的性能的任何想法?
SELECT min(created_at), max(created_at) from info order by id DESC limit 10000
以上查询将为您提供一行,其中包含 info
table 中的最小值和最大值 created_at
。因为它只有 returns 1 行,order by 和 limit 子句不起作用。
倒数第10000条记录可以用order by & limit
条件ORDER BY id DESC LIMIT 1 OFFSET 9999
访问(感谢@Mörre Noseshine指正)
因此,我们可以将预期的查询写成如下:
SELECT
min_created_at.value,
max_created_at.value
FROM
(SELECT
created_at value
FROM info
ORDER BY id DESC
LIMIT 1 OFFSET 9999) min_created_at,
(SELECT
created_at value
FROM info
ORDER BY id DESC
LIMIT 1) max_created_at
如果您想检查按 id
排序的前 10k 行,那么您需要使用子查询来实现您的目标:
SELECT MIN(created_at), MAX(created_at)
FROM (
SELECT created_at
FROM info
ORDER BY id DESC
LIMIT 10000
) tenK
内部查询从 table 中获取前 10k 行,按 id
排序(只需要 created_at
字段)。外部 table 从内部查询生成的结果集中计算 created_at
的最小值和最大值。
我没有 运行 一个 EXPLAIN
但我认为它在 'Extra' 列中说 'Using temporary' (这不好,但你不能做得更好对于此请求)。但是,10,000 行并不算多;它 运行 速度很快,并且性能不会随着 table 大小的增加而降低。
更新:
现在我注意到问题中的这句话:
With this query I want to get the timespan between tha last 10k results.
如果你想获取最近行的 created_at
的值和过去 10k 行的行,那么你可以使用两个简单的查询,这些查询使用 created_at
上的索引运行 快:
(
SELECT created_at
FROM info
ORDER BY id DESC
LIMIT 1
)
UNION ALL
(
SELECT created_at
FROM info
ORDER BY id DESC
LIMIT 9999,1
)
ORDER BY created_at
这个查询产生2行,第一行是过去第10000行的created_at
的值,第二行是最近一行的created_at
的值(我假设created_at
总是在增长)。
我在优化某些考虑了日期时间字段的 sql 查询时遇到问题。
首先,我的table结构如下:
CREATE TABLE info (
id int NOT NULL auto_increment,
name varchar(20),
infoId int,
shortInfoId int,
text varchar(255),
token varchar(60),
created_at DATETIME,
PRIMARY KEY(id)
KEY(created_at));
在对一些简单查询使用解释后,我添加了 created_at 键,这提高了我大部分简单查询的性能。我现在遇到以下查询的问题:
SELECT min(created_at), max(created_at) from info order by id DESC limit 10000
通过此查询,我想获得最后 10k 个结果之间的时间跨度。
使用 explain 后得到以下结果:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE info ALL NULL NULL NULL NULL 4 NULL
关于如何提高此查询的性能的任何想法?
SELECT min(created_at), max(created_at) from info order by id DESC limit 10000
以上查询将为您提供一行,其中包含 info
table 中的最小值和最大值 created_at
。因为它只有 returns 1 行,order by 和 limit 子句不起作用。
倒数第10000条记录可以用order by & limit
条件ORDER BY id DESC LIMIT 1 OFFSET 9999
访问(感谢@Mörre Noseshine指正)
因此,我们可以将预期的查询写成如下:
SELECT
min_created_at.value,
max_created_at.value
FROM
(SELECT
created_at value
FROM info
ORDER BY id DESC
LIMIT 1 OFFSET 9999) min_created_at,
(SELECT
created_at value
FROM info
ORDER BY id DESC
LIMIT 1) max_created_at
如果您想检查按 id
排序的前 10k 行,那么您需要使用子查询来实现您的目标:
SELECT MIN(created_at), MAX(created_at)
FROM (
SELECT created_at
FROM info
ORDER BY id DESC
LIMIT 10000
) tenK
内部查询从 table 中获取前 10k 行,按 id
排序(只需要 created_at
字段)。外部 table 从内部查询生成的结果集中计算 created_at
的最小值和最大值。
我没有 运行 一个 EXPLAIN
但我认为它在 'Extra' 列中说 'Using temporary' (这不好,但你不能做得更好对于此请求)。但是,10,000 行并不算多;它 运行 速度很快,并且性能不会随着 table 大小的增加而降低。
更新:
现在我注意到问题中的这句话:
With this query I want to get the timespan between tha last 10k results.
如果你想获取最近行的 created_at
的值和过去 10k 行的行,那么你可以使用两个简单的查询,这些查询使用 created_at
上的索引运行 快:
(
SELECT created_at
FROM info
ORDER BY id DESC
LIMIT 1
)
UNION ALL
(
SELECT created_at
FROM info
ORDER BY id DESC
LIMIT 9999,1
)
ORDER BY created_at
这个查询产生2行,第一行是过去第10000行的created_at
的值,第二行是最近一行的created_at
的值(我假设created_at
总是在增长)。