Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server查询优化?_Sql Server_Sql Optimization - Fatal编程技术网

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