【发布时间】:2018-02-22 23:41:35
【问题描述】:
用例:
我有桌子,可以说:“制造商”
manuf_code manuf_display_name record_status record_timestamp
---------- ------------------- ------------ ----------------
M000001 Sam N 2017-09-13 12:13:16
M000002 JII N 2017-09-13 15:13:15
M000002 JII U 2017-09-13 17:16:35
M000003 Sun N 2017-09-13 18:54:16
M000004 NG-Graphics N 2017-09-13 19:13:15
M000004 NG-Graphics U 2017-09-14 20:16:50
M000004 NG-Graphics U 2017-09-14 09:13:25
M000005 HewNett N 2017-09-15 10:24:19
M000006 HewNett N 2017-09-15 10:24:19
M000007 HewNett N 2017-09-15 10:24:19
M000007 HewNett U 2017-09-15 15:10:16
M000007 HewNett U 2017-09-17 21:35:19
M000007 HewNett U 2017-09-17 21:37:26
- 当用户创建新制造商时,详细信息位于表中,record_status 为“N”。
- 当用户更新现有制造商时,该制造商 ID 的行将更新为 record_status 为“U”
现在可以有大约 7-10 百万个这样的条目,每个制造商都有:
- 状态为“N”的单个条目
- 状态为“U”的多个条目
要求:我需要获取每个制造商的最新条目。
我的查询:
SELECT m.manuf_code
, m.manuf_display_name
, m.record_timestamp
, m.record_status
FROM manufacturers m
JOIN
( SELECT manuf_code
, MAX(record_timestamp) AS maxdate
FROM manufacturers
WHERE record_status = 'N' OR record_status = 'U'
GROUP
BY manuf_code) mn
ON m.manuf_code = mn.manuf_code
AND m.record_timestamp = mn.maxdate
我更喜欢 Join 子查询,因为前者更快,可以获取大约 700 万个数据。
但是,我需要更快地完成这项工作,因为在我获取这么多数据之后,我什至可能不得不在某个表中插入相同的数据并使用新的 record_status。
请提出建议。
编辑:
CREATE TABLE `manufacturers` (
`manuf_code` varchar(20) NOT NULL,
`record_status` varchar(1) NOT NULL,
`manuf_display_name` varchar(50) NOT NULL,
`record_timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`manuf_code`, `record_update_timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
解释:
新条目将具有状态 --> 'N' 现有条目的更新将具有状态 --> 'U' 而已。查询应该是最新的。
另一种情况,特定于要求是,我们获取每条记录的所有最新条目并将状态设为“L”并再次插入它们
【问题讨论】:
-
record_status 和 manuf_code 上的索引将帮助您使用相同的查询
-
请不要使用随机的产品和语言标签!请与您在表上的索引共享 explsin 的结果。另外,状态是否可以是 N 或 U 以外的任何值?
-
@Shadow 对不起标签。另外,到目前为止,我还没有使用任何索引。我对使用索引不是很熟悉(如果你能指出正确的方向会很有帮助)。
-
您是否每次都必须选择这 700 万条记录,还是一次使用一个 manuf_code?span>
-
解释在哪里?我们还需要看SHOW CREATE TABLE厂商
标签: mysql sql query-optimization greatest-n-per-group