我有一个非常依赖日期的应用程序。它每天存储数千条记录,几乎每个查询都需要检查日期字段以确保它与搜索日期匹配。但随着应用程序的增长,性能正在下降。需要更改应用程序以提高性能,但需要花费大量时间。所以在我开始之前,我希望能够对如何改变它以获得最佳结果有所了解。
目前,日期存储在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
)
答案 0 :(得分: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
目前,您的代码为单行进行了计算,搜索参数(sargs)可能性能不佳
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
注意:
我)分割日期时间,然后限制它们过滤是不可取的
II)表的快速增长 - 在日期分区表时可能是值得的,或者 将旧数据移动到历史表中,因此您只处理较小的数据集。
III)可能值得在insert上设置一个触发器来创建一个名为date的附加列 然后,如果您对应用程序的查询方式有限制,则可以查询。
要求提供更多信息:
I)你能提供关闭表和索引的DDL吗?
II)carid / id / memberid上的当前行计数和计数明显