我在MySQL下表:MySQL的查找不同对每组值的时间间隔
CREATE TABLE `events` (
`pv_name` varchar(60) COLLATE utf8mb4_bin NOT NULL,
`time_stamp` bigint(20) unsigned NOT NULL,
`event_type` varchar(40) COLLATE utf8mb4_bin NOT NULL,
`has_data` tinyint(1) NOT NULL,
`data` json DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=COMPRESSED;
ALTER TABLE `events`
ADD PRIMARY KEY (`pv_name`,`time_stamp`), ADD KEY `has_data` (`has_data`,`pv_name`,`time_stamp`);
我们一直在努力以构建高效的查询,以找到具有在值的至少一个改变每个pv_name
在给定的时间间隔内。
我相信,查询我公司目前已是低效的,因为它只要它发现找到所有在给定的时间间隔的不同值的每个pv_name
,而不是停止不止一个:
SELECT events.pv_name
FROM events
WHERE events.time_stamp > 0 AND events.time_stamp < 9999999999999999999
GROUP BY events.pv_name
HAVING COUNT(DISTINCT JSON_EXTRACT(events.data, '$.value')) > 1;
为了避免这种情况,我考虑拆分的数量和不同的部分为独立的步骤,因为该文件说:
当结合使用DISTINCT LIMIT ROW_COUNT,MySQL作为 找到独特的row_count行就停止。
是否有一个有效的查询找到在给定的时间间隔各pv_name
一对不同的值,在没有找到所有为每个pv_name
不同值在给定的时间间隔?
编辑@Rick詹姆斯
我基本上是试图找到这更快的非光标基础的解决方案:
SET @[email protected]@sql_mode, sql_mode='STRICT_ALL_TABLES';
DELIMITER //
DROP PROCEDURE IF EXISTS check_for_change;
CREATE PROCEDURE check_for_change(IN t0_in bigint(20) unsigned, IN t1_in bigint(20) unsigned)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE current_pv_name VARCHAR(60);
DECLARE cur CURSOR FOR SELECT DISTINCT pv_name FROM events;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE;
SET @t0_in := t0_in;
SET @t1_in := t1_in;
IF @t0_in > @t1_in THEN
SET @temp := @t0_in;
SET @t0_in := @t1_in;
SET @t1_in := @temp;
END IF;
DROP TEMPORARY TABLE IF EXISTS has_change;
CREATE TEMPORARY TABLE has_change (
pv_name varchar(60) NOT NULL,
PRIMARY KEY (pv_name)
) ENGINE=Memory DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
OPEN cur;
label1: LOOP
FETCH cur INTO current_pv_name;
IF done THEN
LEAVE label1;
END IF;
INSERT INTO has_change
SELECT current_pv_name
FROM (
SELECT DISTINCT JSON_EXTRACT(events.data, '$.value') AS distinct_value
FROM events
WHERE events.pv_name = current_pv_name
AND events.has_data = 1
AND events.time_stamp > @t0_in AND events.time_stamp < @t1_in
LIMIT 2) AS t
HAVING COUNT(t.distinct_value) = 2;
END LOOP;
CLOSE cur;
END //
DELIMITER ;
SET [email protected]_sql_mode;
这里的优化是在限制对不同值的数量应用找到每个pv_name
。
“不同的价值观”对我来说并不是说“找到每一个有变化的东西”。请提供一些样本数据和样本输出。 –
如果它有一对值在一个区间中有所不同,那么这个值会在区间中改变。 – Patrick
@RickJames我编辑了这个问题。我希望这有助于澄清它? – Patrick