Sql server SQL Server查询优化?
我有以下疑问:Sql server SQL Server查询优化?,sql-server,sql-optimization,Sql Server,Sql Optimization,我有以下疑问: SELECT tl.*, d.* FROM TrackerLocations AS tl inner join Trackers t on tl.TrackerId = t.TrackerId inner join Devices d on t.UserId = d.UserId WHERE tl.ReceivedTime = (SELECT MAX(tl2.ReceivedTime) FROM TrackerLocations tl2 WHERE tl2.T
SELECT
tl.*, d.*
FROM
TrackerLocations AS tl
inner join Trackers t on tl.TrackerId = t.TrackerId
inner join Devices d on t.UserId = d.UserId
WHERE
tl.ReceivedTime = (SELECT MAX(tl2.ReceivedTime) FROM TrackerLocations tl2 WHERE tl2.TrackerId = tl.TrackerId)
and tl.ReceivedTime >= DATEADD (MINUTE,-2,GETUTCDATE())
and d.OSType <> 3
and d.Notify = 1
…令我惊讶的是,它没有在可接受的时间内返回结果。我第一次在生产环境中运行它,大约需要3秒钟的执行时间。现在,它在C应用程序中一直运行到超时,30秒。
主要目的是:给我任何跟踪器的最新位置和有关用户设备的信息,向后看2分钟。
有关于优化此查询的提示吗
谢谢
索引:
除where子句列以外的任意位置接收时间、OSType、Notify
关于执行计划,这是一件大事,我对它不太熟悉。我应该把它贴在这里吗 我建议尝试在TrackerId、ReceivedTime和ReceivedTime上建立索引。但是,如果没有分析和实际的执行计划,这只不过是瞎猜。在TrackerLocations.TrackerId和Trackers.TrackerId上创建索引。还包括第二次加入的Devices.UserId和Trackers.UserId。最后,看看如何在TrackerLocations.ReceivedTime上为WHERE子句创建索引 一般来说,像这样优化查询的第一个地方是检查您的连接条件上是否有索引。另外,如果您有某种类型的过滤器WHERE子句,那么这可能是添加索引的另一个地方
如果不查看查询执行计划,就很难准确地说出需要优化的位置。很多因素都会影响它,包括每个表中有多少条记录。不过,不要太疯狂地创建索引——它们会影响性能,例如在插入新数据时。最好的建议是使用不同的索引进行测试,看看执行计划是否给了您一些提示。因为我不知道这个查询的执行计划是什么样子,所以我只能继续我认为有助于加快结果的内容 是否有主键和外键约束 然后这些键被索引了吗 除此之外,我将尝试使用CTE限制连接在一起的结果,使其达到未测试的效果:
由于您正在查找最近2分钟内的最新ReceivedTime,因此需要按DESC顺序在ReceivedTime上创建索引。描述订单部分很重要。它还将有助于最大功能。您还可以尝试在ReceivedTime DESC、TrackerID上建立索引。使用常用表表达式限制要联接的行数。您有哪些索引?执行计划是什么样子的?谢谢John和Michael,我将首先尝试在ReceivedTime上创建索引,然后将结果发布在这里!的确使用ReceivedTime>=>限制select max子句。。。显然,这让内心的选择少了很多痛苦。非常感谢。
;WITH cte_loc AS
(
SELECT
tl.*
FROM
TrackerLocations tl
WHERE
tl.ReceivedTime >= DATEADD (MINUTE,-2,GETUTCDATE())
),cte_loc2 AS
(
SELECT
TrackerId
,MAX(ReceivedTime) AS MaxReceivedTime
FROM
cte_loc
GROUP BY
TrackerId
),cte_dev AS
(
SELECT
tl.TrackerId,
d.*
FROM
cte_loc2 tl
INNER JOIN Trackers t ON tl.TrackerId = t.TrackerId
INNER JOIN Devices d ON t.UserId = d.UserId
WHERE
d.OSType <> 3 AND d.Notify = 1
)
SELECT
tl.*, d.*
FROM
cte_loc AS tl
INNER JOIN cte_loc2 tl2 ON tl.TrackerId = tl2.TrackerId
AND tl.ReceivedTime = tl2.MaxReceivedTime
LEFT JOIN cte_dev d ON tl.TrackerId = d.TrackerId
SELECT tl.*,d.*
FROM
TrackerLocations AS tl
inner join Trackers t on tl.TrackerId = t.TrackerId
inner join Devices d on t.UserId = d.UserId
WHERE
tl.ReceivedTime = (SELECT MAX(tl2.ReceivedTime)
FROM TrackerLocations tl2
WHERE tl2.TrackerId = tl.TrackerId
and tl2.ReceivedTime >= @searchTerm)
and d.RegistrationId <> ''
and d.OSType <> 3
and d.Notify = 1