2014-10-02 61 views
1

我有一个非常依赖日期的应用程序。它每天存储数千条记录,几乎每个查询都需要检查日期字段以确保它匹配搜索日期。但随着应用程序的增长,性能正在下降。更改应用程序以提高性能是必需的,但需要很长时间。因此,在我开始之前,我希望了解如何改变它以获得最佳结果。在很多记录上的日期时间搜索性能

当前日期存储在datetime列(带索引)中。在某些情况下,需要时间(EG:您将在2014-10-02 10:24接到信件),有些情况下不是(EG:我需要从2014-10-01到2014-10的每日运输-30)。我想要做的第一件事是分割日期和时间字段,所以当搜索日期时,我不必担心时间。

获取他们使用的特定日期的记录DATEDIFF(D, DateTime, GetDate())=0,但不使用索引(完整扫描)。为了解决我可以使用Datum=DATEADD(dd, 0, DATEDIFF(dd, 0, GetDate()))它使用索引,因此更快。

但我想知道,将日期分为三个单独的列(年,月,日)还是完全跳过日期函数会更快?还是有另一种方法来显着加快速度?

例/原因分裂:

Table members: Id, MemberId, Datetime, CarId 
Table car: Id, Name 

我今天需要推动所有的汽车名单。所以:

SELECT Id, Name 
FROM Car 
WHERE Id IN (
    SELECT CarId 
    FROM Members 
    WHERE DATEDIFF(D, DateTime, GetDate())=0 
) 

现在,如果日期时间将被分隔,我可以使用(使用索引)

SELECT Id, Name 
FROM Car 
WHERE Id IN (
    SELECT CarId 
    FROM Members 
    WHERE Date=DATEADD(dd, 0, DATEDIFF(dd, 0, GetDate())) 
) 

现在我想显示特定车/日,所有成员为了。

SELECT * 
    FROM Members 
    WHERE Date=DATEADD(dd, 0, DATEDIFF(dd, 0, GetDate())) 
    AND CarId=1 
    ORDER BY Time -- new split col 

但也许它甚至更快的将它拆分了一些更多的使用

SELECT Id, Name 
FROM Car 
WHERE Id IN (
    SELECT CarId 
    FROM Members 
    WHERE Year=2014 
    AND Month=10 
    AND Day=2 
) 
+2

我怀疑分裂日期和时间可能实际上降低性能。你可以在你认为有帮助的地方添加一个示例查询,以便我们更好地理解动机或者可能提出一种替代方法? – 2014-10-02 08:23:08

+0

那么从第一次开枪看起来好像不是问题,但是可以提供表格的数据结构和完整的查询。还有,你有多少条记录? – 2014-10-02 08:44:22

+0

更新的问题。大约100,000个记录将每月添加到某些表中,因此如果没有正确更改,性能将快速下降 – 2014-10-02 08:49:27

回答

0

我在下面提供了一些优化的SQL,但更多的信息将是有益的。此外,你的表和索引的DDL将有助于提供洞察力。

1)汽车今天带动

select c.id, c.name 
from members as m 
inner join car as c 
on c.Id = m.CarId 
where 
    m.datetime < '2014-10-04 00:00:00' 
    and m.datetime >= '2014-10-03 00:00:00' 

-- you could pipe that date calculation into the genated sql 
-- or work with the getDate function and use ceiling 

where 
    m.datetime < DATEADD(day,1,CONVERT (date, GETDATE())) --tomorrow 
    and m.datetime >= CONVERT (date, GETDATE()) --today 

目前你的代码doed永远单列计算并没有对搜索参数表现不佳(个SARG)

2)列表中的所有潜在的名单成员,特定的汽车和日期依次是:

select m.* 
from members as m 
where 
    m.carId = 1 
    and m.datetime < '2014-10-04 00:00:00' 
    and m.datetime >= '2014-10-03 00:00:00' 
order by m.datetime 

注:

I)日期时间被分割,然后对他们的限制过滤是不可取的

II)表的快速增长 - 它同时日期分区表或 较旧的数据移动到历史表,所以你”可能是值得的只处理较小的数据集。

III)也许值得在插入时设置一个触发器来创建一个名为日期 的额外列,然后您可以查询是否对应用程序查询的方式有限制。请

其他信息:

我),你可以提供DDL关闭表和索引?

II)当前的行数,并依靠carid/ID不同/ MEMBERID