请求表:
requests
+id (INT) AUTO_INCREMENT
+title (VARCHAR)
状态表:
statuses
+id (INT) AUTO_INCREMENT
+title (VARCHAR)
关系表:
request_status (MANY TO MANY)
+id (INT) AUTO_INCREMENT
+request_id (INT) Foreign Key
+status_id (INT)
我只想统计当前 status_id为2 的那些请求。当前请求的状态(status_id)是request_status表中的最后一个。
如果数据约为1600k,那将是完美的高性能查询
答案 0 :(得分:1)
假设最新状态是ID最大的状态:
SELECT COUNT(*)
FROM request_status
WHERE status_id = 2
AND NOT EXISTS (
SELECT 1
FROM request_status AS x
WHERE request_id = request_status.request_id
AND id > request_status.id
)
或者这个:
SELECT COUNT(*)
FROM (
SELECT 1
FROM request_status
GROUP BY request_id
HAVING MAX(CASE WHEN status_id = 2 THEN id END) = MAX(id)
) AS x
您将需要一些索引。我建议创建这些:
KEY ix1 (request_id, status_id)
KEY ix2 (status_id, request_id)
答案 1 :(得分:0)
SELECT COUNT(*) FROM request_status WHERE status_id = 2;
如果我正确理解了您的问题,该方法应该最好地工作-应该计算status_id等于2的对。
答案 2 :(得分:0)
关系表的架构效率低下。我将与他们讨论here。
但是,相反,让我们更改架构以使其更加高效。而不是3个具有多对多映射的表,而只有一个表:
CREATE TABLE requests (
id ...,
latest_status ENUM('eating', 'sleeping', 'running'),
all_statuses SET('eating', 'sleeping', 'running'),
) ENGINE=InnoDB;
(或者,您可以使用TINYINTs
,但使用不同的语法。)
给定request
的状态更改时,请设置latest_status
并将新状态“或”设置为all_statuses
。
要检查最新的running
:WHERE latest_status = 'running'
。
或者,如果使用某些数值:WHERE latest_status = 2
。