TSQL或查询计划提示

TSQL或查询计划提示,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我可以使用何种查询提示来提高OR查询的性能 下面的两个查询分别立即运行并返回0行 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.Appointme

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

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

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'
海选信息是一个视图

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

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

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

更新:

AuditInfo视图的定义如下:

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

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

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'
至于明天的演出。
为了稳定,我将接受工会而不是加入或加入工会。

使用联合SQL,一次只执行一个查询,查询优化器变得愚蠢的可能性更小

appointmentidworkey
AppointmentIdForChange
objectname
是否索引?它们都对应于两个不同表上的索引列。我们在这里讨论的表的大小是多少?我假设
AppointIDForChange
AppointIDWorkey
是类型
INT
objectname
VARCHAR
NVARCHAR
?@Jeff:这些结果一致吗?通常,
索引搜索
会导致更快的执行时间。另外,我想知道您是否为数据库启用了
read\u committed\u snapshot
。根据表名,我猜这个表上有很多写活动,默认情况下SQLServer编写器会阻止读卡器……因此它们对应于两个不同表上的索引列。问题是它们是否在海选信息中编入索引?请发布实际的查询计划和表定义。键查找使用聚集索引。union执行与OR相同的操作。联合所有的工作都很好,但不能产生预期的结果。选择DISTINCT*FROM(…UNION ALL…)有效…但有点冗长,所以与(…UNION ALL…)有效。10分钟减到几分之一秒,但你却因为它冗长而不予理睬?不是不予理睬。。。我只是想弄清楚它为什么会起作用,也许我可以强制执行distinct plus union似乎都会产生的理想执行计划。执行计划似乎如此不稳定,这一事实让我担心依赖它作为解决方案。冗长或不稳定反对意见是什么?你有证据证明这个解决方案不稳定吗?您甚至没有意识到带有连接的视图是相关的。没有理由令人讨厌。我在我原来的帖子中指出了这一观点。这很重要,因为我需要一种方法来确保SQL选择一个好的执行计划,无论是现在还是两周后。性能上存在如此巨大的差异这一事实让我想到,随着表中数据的更改,SQL可能会在两周后突然选择一个完全不同的(糟糕的)执行计划。您是否有证据表明,在给定一个独特的+UNION ALL的情况下,SQL将始终使用相同的执行计划?
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'