如何提高查询性能

时间:2012-09-08 13:50:44

标签: sql sql-server sql-server-2000

使用SQL Server 2000

假期(表)

dates

2012-08-02 
2012-08-19 
2012-08-20 

表1

id dates time

001 01/08/2012 00:00
001 02/08/2012 00:00
001 03/08/2012 00:00
001 04/08/2012 12:00
...
...
001 17/04/2012 11:00
001 18/08/2012 00:00
001 19/08/2012 00:00
001 20/08/2012 00:00
001 21/08/2012 12:00
...

我想检查每列的上一个日期和下一个日期,然后我想更新现在或缺席或假期。

条件的

  • 如果当前行时间不等于00:00,则状态应为P(存在)
  • 如果上一个日期时间列为00:00且下一个日期时间列为00:00,则自动当前行状态应为AB(缺席),
  • 如果日期等于假期表日期,则自动当前行状态应为H

注意:此查询正在运行,没有任何失败,只关注是耗时...

查询

Select 
    t2.id, 
    t2.dates, 
    case 
        when t2.time <> '00:00' 
            then 'P' 
        when t4.dates = t2.dates and t1.intime = '00:00' and t3.intime = '00:00' 
            then 'AB' 
        else 'H' 
    end as attn 
from
    (
        Select id, dates, time from table1 
        where t1.dates = Cast('18/08/2012' as datetime)
    ) t1 
    left outer join
    (
        Select id, dates, time from table1 
        where t2.dates = Cast('19/08/2012' as datetime)
    ) t2 
    on t1.id = t2.id
    left outer join 
    (
        Select id, dates, time from table1 
        where t2.dates = Cast('20/08/2012' as datetime)
    ) t3 
    on t2.id = t3.id
    left outer join 
    (
        select dates from holiday
    ) t4 
    on t4.dates = t2.dates

以上查询工作正常,但显示时间较长,因为我想查看每个01/09/2012的{​​{1}}到30/09/2012的数据,我有n个ID, 系统正在检查每个ID的上一个日期和下一个日期并显示结果。

用于显示数据的任何其他替代查询或解决方案

2 个答案:

答案 0 :(得分:1)

正如戈登所说,你的结构很好,但我可以推荐你另一种方式来提高这个查询(或任何其他重要的)的性能,即使用数据库引擎优化顾问

使用此工具,SQL Server将尝试创建其他索引,统计信息以及其他可以提高所提供查询性能的内容。

要启动它,请从查询窗口中选择查询文本,右键单击,然后选择在数据库引擎优化顾问中分析查询

enter image description here

答案 1 :(得分:0)

你的基本查询结构很好。就个人而言,我不会硬编码子查询中的日期,而是将日期添加到“on”子句中。

您可以通过在(id,date)上创建索引来加快运行速度:

create index table1_id_date on table1(id, date)

假期指数也可能有所帮助:

create index holiday_date on holiday(date)

您还可以升级到更新版本的SQL Server。由于lag()和lead()函数,您的查询将更快,更容易在SQL Server 2012中表达。