2013-07-17 55 views
0

我有了的SQL Server查询性能问题

  • 非唯一ID列的表
  • 各种数据

  • 正列时数据的日期已更新

    我有一个查询,给定一个日期范围,它获取在该日期范围内更新的条目列表以及它刚刚找到的最后一个更新之前的条目列表。通常日期范围在一天之内,因此07-10-2013 00:00:000 - 7-11-2013 00:00:000。

    例如。鉴于2013年7月10日00:00:000 - 2013年7月11日00:00:000,查询结果2项

    id new data  updatedate    old data  last updatedate 
    3 randomdata 7-10-2013 03:30:343  randomdata 7-05-2013 06:34:764 
    4 randomdata 7-10-2013 13:30:343  randomdata 6-09-2013 04:37:376 
    

    这是结果,我想获得。目前,我已经有了一个查询,但是查询速度很慢,因为表中有3个内部联接,这些联接有很多条目,我想知道是否有人可以想出一种更快的查询方式。使用SQL Server 2000

    表信息

    • 非唯一ID
    • 唯一的ID(这仅仅是一个自动递增ID)
    • 将收集的各种数据
    • 更新日期

    编辑:

    我ndexes目前都在idupdatedate

    查询我目前使用(概括的话)::警告::这不是漂亮::警告::

    select * 
    from 
        (select distinct 
         s1.id as id, 
         s1.randData1, s2.randData1, s1.randData2, s2.randData2,..., 
         s1.updatedate as newupdatedate, 
         s2.updatedate as prevupdatedate, 
         datediff(second, s1.updatedate ,s2.updatedate) as maxdate 
        from 
         (select * 
         from updates 
         where updatedate >= '{0}' and updatedate < '{1}' 
          and id in ('{3}')) as s1 
        inner join 
         updates s2 on s1.id = s2.id and s1.updateid != s2.updateid) as t1 
    inner join 
        (select 
          s1.id, max(datediff(second, s1.updatedate, s2.updatedate)) as maxdate2 
         from updates s1 
         inner join updates s2 on s1.id in ('{3}') and s1.id = s2.id and s1.updateid != s2.updateid 
         where datediff(second, s1.updatedate, s2.updatedate) < 0 
         and s1.updatedate < '{1}' and s2.updatedate < '{1}' 
         group by 
         s1.id) as t2 on t1.id = t2.id and t1.maxdate = t2.maxdate2 
    

    {0 } {1}和{2}是传入的参数。

    编辑:如果有什么区别,查询正在C#中执行。如有必要,2个查询也会很好。我最终寻找的是在所选日期的数据中发生了什么变化。

  • +2

    你能发布查询,并告诉我们在什么地方指标? –

    回答

    0

    我已经有了相当好的运气,将所有嵌套的select语句放到#Temp表中。取决于你真的在说些什么,你可能会使用表变量。

    还可以逐步检查您的查询,看看您是否确实需要在每个嵌套查询中携带所有数据。换句话说,所有的嵌套查询都会被外部查询使用,或者是额外的数据。

    我认为在这里使用临时表的复杂性将是你最好的选择。这样,所有的嵌套查询都可以构建临时表,而不必将它们保存在内存中。

    您的最终查询将更加紧凑和快得多。

    +0

    第一个执行不同randData的内部查询是我正在查找的数据,第二个maxdate2用于查找所选中之前的日期条目。我试图尽可能地限制内连接的内容,因为我对Sql性能的了解很少。我想如果第一个外部表有最小数量的条目,那么外部内部联接会更快。希望这不是太混乱。 – LazyProgrammer

    +0

    只需要多条语句。让你的嵌套select语句设置在一些真正的表中,然后在完成时截断它们。这样,你只有一条select语句,它正在回看磁盘上不在内存中的表。 – TTUGecko

    0

    尝试使用临时表 -

    IF OBJECT_ID (N'tempdb.dbo.#temp') IS NOT NULL 
        DROP TABLE #temp 
    
    SELECT * 
    INTO #temp 
    FROM dbo.updates 
    WHERE ID IN ('{3}') 
    
    SELECT * 
    FROM 
        (
        SELECT DISTINCT 
          s1.id AS id, 
          s1.randData1, s2.randData1, s1.randData2, s2.randData2, 
          s1.updatedate AS newupdatedate, 
          s2.updatedate AS prevupdatedate, 
          DATEDIFF(second, s1.updatedate ,s2.updatedate) AS maxdate 
        FROM 
        (
          SELECT * 
          FROM #temp 
          WHERE updatedate BETWEEN '{0}' AND '{1}' 
        ) s1 
        JOIN #temp s2 ON s1.id = s2.id AND s1.updateid != s2.updateid 
    ) t1 
    JOIN (
        SELECT 
          s1.id, 
          MAX(DATEDIFF(second, s1.updatedate, s2.updatedate)) AS maxdate2 
        FROM #temp s1 
        JOIN #temp s2 ON s1.id = s2.id AND s1.updateid != s2.updateid 
        WHERE DATEDIFF(second, s1.updatedate, s2.updatedate) < 0 
          AND s1.updatedate < '{1}' AND s2.updatedate < '{1}' 
        GROUP BY s1.id 
    ) t2 ON t1.id = t2.id AND t1.maxdate = t2.maxdate2 
    
    +0

    问题在于我在C#中运行查询,所以我不确定这是否可行,因为有2个select语句。对不起,我可能应该添加到原始文章。 – LazyProgrammer