我遇到了SQL查询问题。
我正在使用MariaDB。我有一个包含多个字段的表,我想在更改值时选择行。
例如:
+------------+----------+----------+
| time_stamp | G1.state | G2.state |
+------------+----------+----------+
| 1433717821 | 3 | 1 |
+------------+----------+----------+
| 1433717881 | 3 | 1 |
+------------+----------+----------+
| 1433717942 | 5 | 1 |
+------------+----------+----------+
这里我需要在3次更改为5时获取time_stamp。我已尝试过以下查询:
SELECT a.`time_stamp`, a.`G1.state`, `G2.state`
FROM `regs` AS `a`
WHERE ((a.`G1.Estado` <>
(SELECT b.`G1.state`
FROM `regs` AS `b`
WHERE a.time_stamp > b.time_stamp
ORDER BY b.time_stamp DESC
LIMIT 1)) OR
(a.`G2.state` <>
(SELECT b.`G2.state`
FROM `regs` AS `b`
WHERE a.time_stamp > b.time_stamp
ORDER BY b.time_stamp DESC
LIMIT 1))) AND
(a.time_stamp >= 1433159549) AND (a.time_stamp < 1433677949)
ORDER BY a.time_stamp ASC
然而,运行时间太长,需要50.96秒,而且我需要它更快(希望不到一秒钟)。它分析大约10k的值。谁能帮我一把?
答案 0 :(得分:2)
您可以使用变量来跟踪G1.state
或G2.state
列中的更改:
SELECT time_stamp, `G1.state`, `G2.state`
FROM (
SELECT time_stamp, `G1.state`, `G2.state`,
IF (@g1 IS NOT NULL AND @g1 <> `G1.state`,
IF(@g1:= `G1.state`, 1, 1),
IF(@g1:= `G1.state`, 0, 0)) AS g1Changed,
IF (@g2 IS NOT NULL AND @g2 <> `G2.state`,
IF(@g2:= `G2.state`, 1, 1),
IF(@g2:= `G2.state`, 0, 0)) AS g2Changed
FROM mytable, (SELECT @g1:= NULL, @g2:= NULL) AS vars
ORDER BY time_stamp ASC ) t
WHERE g1Changed = 1 OR g2Changed = 1
此查询可能表现更好,因为没有使用相关的子查询。
注意:根据MariaDB documentation:
读取用户定义的变量并在同一语句中设置其值是不安全的(除非该命令是SET),因为这些操作的顺序是未定义的。
要解决此问题,请使用嵌套条件:@g1
或@g2
首先分别与G1.state
,G2.state
值进行比较,并且<设置em> then ,以便在获取下一条记录时再次进行比较。
答案 1 :(得分:0)
Select * from regs a
Where time_stamp=
(Select Max(time_stamp) from regs
Where time_stamp< a.time_stamp)
and 'g1.state' <> a.'g1.staTE'
order by a.time_stamp
答案 2 :(得分:0)
您可以使用索引加快查询速度。最好的指标是
regs(time_stamp, `G1.state`, `G2.state`)
注意:在列名中使用.
等字符是真的不良做法。