sql - 优化带数据时间过长的SQL查询
问题描述
我正在尝试查询一个医疗保健系统,该系统在没有任何评估的情况下计算患者人数(患者在访问诊所时进行的活动)。我想过滤掉特定网络、用户和诊所的结果。
这是我的查询:
select count(*) as Qualify from
UserClinic uc
INNER JOIN Patient p on p.DefaultClinicId = uc.ClinicId and uc.UsersId = 47 and p.NetworkId = 2
where
p.ActivePatient = 1
and p.deleted = 0
and not exists(select * from PatientToxicologyTesting ptt where ptt.PatientID = p.PatientID)
and not exists(select * from PatientPrescriptionRegistry ppr where ppr.PatientID = p.PatientID)
and not exists(select * from PatientPillCount pc where pc.PatientID = p.PatientID)
and not exists(select * from PatientControlledSubstanceAgreement csa where csa.PatientID = p.PatientID)
and not exists(select * from PatientHealthAssessment mha where mha.PatientID = p.PatientID)
UserClinic 是 User 和 Clinic 之间的多对多关系表。患者链接到网络和诊所。
上面的查询需要 3 分钟的访问时间才能执行,如果我从查询中删除 UserId 或 NetworkId 加入条件,这个时间会大大减少到 1 秒。
有人可以建议一个更好的方法来编写这个查询吗?
编辑
这是查询的执行计划
解决方案
几个小贴士:
- 如果您对尝试像这样选择的特定值不感兴趣,请不要使用“COUNT(*)”或“SELECT *”。我建议使用 'COUNT(1)' 或 'SELECT 1'
- 仔细检查您在部分
PatientID
使用的表的列上是否有索引。NOT EXISTS
应检查这些表:PatientToxicologyTesting, PatientPrescriptionRegistry, PatientPillCount, PatientControlledSubstanceAgreement and PatientHealthAssessment
。您有 CLUSTER INDEX SCAN 这意味着索引丢失或碎片。如果索引高度碎片化,则重建/重组它。 您可以在表上创建过滤索引
Patient
以支持此查询Create Index IX_Patient_Filter_1 ON Patient(NetworkId,DefaultClinicId) WHERE ActivePatient = 1 AND deleted = 0
UserClinic
您可以在表上创建支持索引Create Index IX_UserClinic_1 ON UserClinic(UsersId,ClinicId )
推荐阅读
- javascript - 为什么将新创建的元素插入现有元素会解析 [Object HTMLElement]?
- bash - error while running shell script through jenkins pipeline
- git - How do I limit what I pull down for my gatsby site from my repo?
- android - 相同的数据出现在整个 recyclerview 中
- angularjs - Tabs navigation issue with search button?
- javascript - 匿名函数名称未显示
- java - 使用java在EPS文件中添加元数据
- kotlin - 如何从 Kotlin AllOpen 插件中排除注释?
- java - 禁用 NamedParameterJdbcTemplate 缓存
- javascript - find 方法如何与数组一起使用?