首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TSQL或查询计划提示

TSQL或查询计划提示
EN

Stack Overflow用户
提问于 2013-05-07 23:32:36
回答 1查看 304关注 0票数 2

我可以使用哪种查询提示来提高OR查询的性能。

下面的两个查询分别立即运行并返回0行。

代码语言:javascript
复制
SELECT * FROM AuditInfo ai
WHERE (ai.AppointmentIdForChange = 60231)
and ai.objectname = 'dbo.Appointments'

SELECT * FROM AuditInfo ai
WHERE (ai.AppointmentIdForKey = 60231)
and ai.objectname = 'dbo.Appointments'

AuditInfo是一种视图。

但是,以下查询将永远运行(10+分钟)

代码语言:javascript
复制
SELECT * FROM AuditInfo ai
WHERE (ai.AppointmentIdForKey= 60231 OR ai.AppointmentIdForChange = 60231)
and ai.objectname = 'dbo.Appointments'

我该如何改进这一点呢?是否有我可以使用的查询提示?

在估计的执行计划中,我可以看到单个查询使用键查找,而使用OR语句的查询使用索引查找(它占用了74%的成本)。

更新:

AuditInfo视图的定义如下:

代码语言:javascript
复制
ALTER VIEW AuditInfo
AS
SELECT 
    ae.Id
    ,ae.AuditDateTime AS DateTime
    ,ae.ChangeTypeId
    ,ae.ObjectName
    ,aek.KeyName
    ,aek.KeyValue
    ,aek.KeyValueNumeric
    ,ae.UserId
    ,ae.HostName
    ,ae.ServerName
    ,aec.OldValue   
    ,(SELECT TOP 1 aecNewValue.OldValue AS Value
        FROM dbo.AuditEntries aeNewValue
        JOIN dbo.AuditEntryKeyValues aekNewValue ON aeNewValue.Id = aekNewValue.AuditEntryId AND aek.KeyName = aekNewValue.KeyName AND aek.KeyValueNumeric = aekNewValue.KeyValueNumeric
        JOIN dbo.AuditEntryChanges aecNewValue ON aeNewValue.Id = aecNewValue.AuditEntryId AND aec.ColumnName = aecNewValue.ColumnName
        WHERE aeNewValue.ChangeTypeId IN (0, 1) AND aeNewValue.AuditDateTime > ae.AuditDateTime AND aeNewValue.ObjectName = ae.ObjectName
        ORDER BY aeNewValue.AuditDateTime 
    ) AS NewValue
    ,appointmentForKey.AppointmentId AS AppointmentIdForKey, appointmentForChange.AppointmentId AS AppointmentIdForChange
FROM dbo.AuditEntries ae
JOIN dbo.AuditEntryKeyValues aek on ae.Id = aek.AuditEntryId
LEFT JOIN dbo.AuditEntryChanges aec on ae.Id = aec.AuditEntryId AND aec.ColumnName IN ('PatientId', 'AppointmentId')

-- Get AppointmentId
LEFT JOIN dbo.Appointments appointmentForKey ON aek.KeyName = 'AppointmentId' AND aek.KeyValueNumeric = appointmentForKey.AppointmentId
LEFT JOIN dbo.Appointments appointmentForChange ON aec.ColumnName = 'AppointmentId' AND aec.OldValueNumeric = appointmentForChange.AppointmentId

GROUP BY ae.Id, ae.AuditDateTime, ae.UserId, ae.ChangeTypeId, ae.ObjectName, ae.HostName, ae.ServerName, aek.KeyName, aek.KeyValue, aek.KeyValueNumeric, aec.OldValueNumeric, aec.OldValue, aec.ColumnName
,appointmentForKey.AppointmentId, appointmentForChange.AppointmentId
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-07 23:40:02

我知道您要求查询提示,但您可以将其作为具有联合的两个查询来运行

代码语言:javascript
复制
SELECT * FROM AuditInfo ai
WHERE (ai.AppointmentIdForChange = 60231)
and ai.objectname = 'dbo.Appointments'
UNION
SELECT * FROM AuditInfo ai
WHERE (ai.AppointmentIdForKey = 60231)
and ai.objectname = 'dbo.Appointments'

至于明天会不会上演。

为了稳定,我将接受UNION而不是JOIN或or。

使用联合SQL,一次只做一个,查询优化器不太可能变得愚蠢。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16423002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档