当从当前行中减去前一行时,查询速度太慢,是否有更有效的方法来执行此操作? 我正在尝试创建一个数据过滤器,它能够突出显示顺序发生的事件。我有一张机器操作数据'源'表,按时间顺序排序。使用WHERE子句我过滤掉与此特定分析不太相关的数据。其余数据将插入到“已过滤”的新表中。使用来自'source'的插入的ID号,我将每一行与其前一行进行比较以找出值的差异 - 如果差值为1,则事件按顺序发生,如果差异为null,则它们没有。我的问题是将行与前一行进行比较所需的时间长度。根据MySQL Workbench操作输出,我已将数据量减少到完整卷的2.5%(275000行),查询需要3012秒。我已经尝试过以不同方式构建查询,但最终已达到死胡同。所以我的问题是 - 是否有更有效的方法来比较一行与前一行?
好的 - 这里有更多细节。
/*First I create the table for the filtered data */
drop table if exists filtered_dta;
create table filtered_dta
(
ID int (11) not null auto_increment,
IDx1 int (11),
primary key (ID)
);
/ 然后我插入过滤后的数据 /
insert into filtered_dta (IDx1)
select seq from source
WHERE range_value < -1.75
and range_value > -5 ;
/* Then I compare each row with its previous */
select t1.ID, t1.IDx1,(t1.IDx1-t2.IDx1)
as seq_value
from filtered_dta t1
left outer join filtered_dta t2
on t1.IDx1 = t2.IDx1+1
order by IDx1
;
以下是样本表。
Table - filtered_dta Results
| ID | IDx1 | | ID | IDx1 | seq_value |
1 3 1 3 null
2 4 2 4 1
3 7 3 7 null
4 12 4 12 null
5 13 5 13 1
6 14 6 14 1
源表中的完整数据集预计在3到1千万行之间。数据库将创建并使用大约50个表。该数据库被用作模拟软件的后端引擎,该软件无法处理这一数据量并对数据所代表的系统进行适当的分析。 我花了一些时间在这个问题上并遇到了以下问题; find_seq表可能是使用myISAM创建的,并且需要转换为innoDB表。我试图将默认引擎设置为innoDB,但没有看到明显的差异。 这个问题在查询慢MySQL query painfully slow on large data的问题上是类似的 - 但它的问题在于在where子句中有一个函数 - 从我的动作输出我可以看到where子句不是太慢。 我很感激任何人可能对此有任何意见。此外,我不是MySQL的熟练用户,所以如果可能的话给出详细信息。 亲切的问候。
答案 0 :(得分:0)
您可以使用类似此模板的内容来识别顺序&#34;岛屿&#34;没有自我加入:
SELECT @island := @island + IF(seqId <> @lastSeqId + 1, 1, 0) AS island
, orderQ.[fieldsYouWant]
, @lastSeqId := seqId
FROM (
SELECT [fieldsYouWant], [sequentialIdentifier] AS seqId
FROM [theTable] AS t
, (SELECT @island := 0, @lastSeqId := [somethingItCannotBe]) AS init_dnr -- Initializes variables, do not reference
WHERE [filteringConditionsMet]
ORDER BY [orderingCriteria]
) AS orderingQ
;
我尽量保持它尽可能通用,但是你要注意我必须回到假设seqId
是数字并且预计会增加1。如果需要,island
计算中的条件可能会复杂得多(对于(A, 1), (A, 2), (B, 3)
应该是两个岛的情况,基于未由单个值定义的序列)。
您可以进一步采用此模板,以识别&#34; island&#34;通过简单地将上述查询作为子查询来实现边界和大小:
SELECT island, MIN(seqId), MAX(seqId), COUNT(seqId)
FROM ([above query]) AS islandQ
GROUP BY island
;