我正在使用Microsoft的SQL Server 2012 Express。数据库/数据大小从小到中等,仅包含50个表,尽管某些表确实具有100k-200k记录。给我带来麻烦的查询确实在较大的表之一(time_list)上运行。
涉及的表:
坏消息:当前表除了PK / FK之外没有其他索引
问题:
我有一个查询(见下文),运行速度非常慢,执行速度取决于应用于查询的日期过滤器,但是运行缓慢的原因却很直观。
基于以下我的测试案例的观察:
看来,一旦我尝试在2019年内查询任何内容,就会破坏性能。
有趣的是,我可以查询巨大的日期范围,并且一切运行良好,但是2019年的一个非常具体的范围导致查询停顿。 我什至通过完全删除日期过滤器来运行查询,它在681毫秒内执行。
此问题在LIVE服务器和测试服务器上可见,并且可以通过在查询中使用日期过滤器来重现。尽管硬件有所不同,但两台服务器的时延都非常相似。
让我介绍一下测试用例(日期过滤器应用在查询的底部):
没有日期过滤器,查询返回结果集中最多的记录。
日期过滤范围:t.date在“ 1900-01-01”和“ 2019-03-31”之间
时间范围:〜119年
日期过滤范围:t.date在“ 2019-01-01”和“ 2019-03-06”之间
时间范围:〜3个月
日期过滤范围:t.date在“ 2018-03-01”和“ 2019-03-31”之间
时间范围:〜1年
实际查询:
select
result.JobId as ProjectId, job.file_number as FileNumber,
job.street_name1 as ProjectAddress, addr.StreetMetadata as AddressMetadata,
client.client_number as ClientNumber,
pln.Lot as PlanLot, pln.plan_number as PlanNumber,
result.TimeDate as TimeDate
from
(select distinct
job.entity_id as JobId, job.client_entity_id as ClientId,
(select top 1 t2.date
from time_list t2
inner join Code_Department_Types dept2 on dept2.entity_id = t2.department_id
inner join Code_Billing_Types bill2 on bill2.entity_id = t2.billing_id
where (t2.job_id = job.entity_id and ((bill2.name='L/O on GRADE' and dept2.name='F')))
order by t2.date desc) as TimeDate
from
time_list t
inner join
Code_Department_Types dept on dept.entity_id = t.department_id
inner join
Code_Billing_Types bill on bill.entity_id = t.billing_id
inner join
Job_Info job on t.job_id = job.entity_id
where
EXISTS (select t.entity_id FROM time_list t1
inner join Code_Department_Types dept on dept.entity_id = t1.department_id
inner join Code_Billing_Types bill on bill.entity_id = t1.billing_id
where
t1.job_id = job.entity_id and (bill.name='L/O on GRADE' and dept.name='F')
) and not
EXISTS (select t.entity_id FROM time_list t1
inner join Code_Department_Types dept on dept.entity_id = t1.department_id
inner join Code_Billing_Types bill on bill.entity_id = t1.billing_id
where
t1.job_id = job.entity_id and (bill.name='SRPR' and dept.name='F')
)
and t.date between '1900-01-01' AND '2019-03-31' -- FAST! (1.1 sec)
--and t.date between '2019-01-01' and '2019-03-06' -- SLOW (1:40)
--and t.date between '2018-03-01' AND '2019-03-31' -- SLOW (> 6 mins, and still going, had to stop it)
) as result
inner join Companies client on client.entity_id = result.ClientId
inner join Job_Info job on job.entity_id = result.JobId
inner join Job_Address addr on addr.JobId = job.entity_id
inner join Job_Plans pln on pln.job_id = result.JobId
order by FileNumber asc;
答案 0 :(得分:1)
正如帖子所指出的,在日期字段上添加索引可立即解决问题。我将对此进行监视,但现在将此帖子标记为“已回答”。
答案 1 :(得分:0)
您的注释中指定了有关更新日期参数的运行时间增量,这表明存在一些数据完整性问题。这有帮助吗?
CAST(t.[Date] AS DATE) BETWEEN '1900-01-01' AND '2019-03-31'