【发布时间】:2015-02-03 21:29:57
【问题描述】:
我们有两台设备以大约 30 秒的间隔收集数据。这些设备位于两个相距较远的地点。每个站点的每次收集的绝对时间可以变化 +/- 30 秒。有时,网站会因各种原因下线。每个设备的数据代表不同类型的测量,例如来自设备 1 的温度和来自设备 2 的湿度。一个进程将来自 device1 和 device2 的数据记录到 SQL Server 2012 Express 数据库中的单独表中,该数据库在与每个设备分开的服务器上运行。
希望将来自两个设备的数据关联到记录中,这些记录将包含具有特定日期/时间的 site1 值的列,如果有任何可用的数据,则结合 site2 的数据。然后,用户程序将请求指定日期/时间范围的记录集。为此,我构建了以下SP:
ALTER PROCEDURE [db_datareader].[DataJoinDateRange]
@DateFrom DateTime = '2014-05-15 15:10:24.000',
@DateTo DateTime = '2014-06-15 15:10:24.000'
AS
BEGIN
SET NOCOUNT ON;
WITH site1(id, date_time, dataval)
AS
(
SELECT *
FROM site1_data
WHERE site1_data.date_time BETWEEN @DateFrom AND @DateTo
),
site2(id, date_time, datavaql)
AS
(
SELECT *
FROM site2_data
WHERE site2_data.date_time BETWEEN @DateFrom AND @DateTo
)
SELECT * from site1 site1_res
INNER JOIN (select id, date_time, data_val) site2_res
on ABS(DATEDIFF("SECOND", site1_res.date_time, site_2_res.date_time)) < 30
END
目的是首先选择所需日期/时间范围内的记录,然后将站点 1 中的记录连接到站点 2 中在 +/- 30 秒内的记录。范围。结果记录集将包含来自两个设备的数据,或者在不存在相应记录时为空。
这似乎可行:具有所需形式的记录被输出并对应于每个表中的正确记录。但是执行速度很慢。在几周的日期范围内进行查询大约需要 1 分 30 秒。 Site1 在此日期范围内包含大约 5000 条记录,而 Site2 仅包含 1 条记录。仅针对每个表的日期范围的 SELECT 查询将在不到一秒的时间内执行。
我以前从未深入研究过 SQL,但我们这个小组目前没有其他人来完成这项任务。谁能告诉我正确的方法来做到这一点,或者至少如何加速这个 SP?
【问题讨论】:
-
您能否在加载数据时编辑表中的 date_time 字段,使其始终为 :00 或 :30 或为此添加一个新字段(日期时间或整数),而不是计算 datediff?
-
当我想加快查询速度时,我总是求助于索引,看看是否可以为手头的任务创建索引。您还可以创建跨表的索引。
-
您的子查询在查询中没有表。然后你有 nonSARGable 谓词,因为你有你的列在一个函数中。最后但并非最不重要的是,您有一个三角形连接。 sqlservercentral.com/articles/T-SQL/61539
-
JamesZ,数据上的时间戳本质上是可变的,我必须从 site2 中找到与给定 site1 记录中的时间戳“足够接近”的记录(如果有的话)。所以我总是需要做一些计算来确定来自 site2 的哪些(如果有的话)记录是合适的。
-
Reenactor Rob - 我确实为两个表中的 date_time 字段创建了索引。创建一个结合两个表的索引听起来很有趣,我将不得不找出如何做到这一点并尝试一下。
标签: sql sql-server sql-server-2008 sql-server-2012 sql-server-2008r2-express