如何强制SQL Server按特定顺序执行查询

如何强制SQL Server按特定顺序执行查询,sql,sql-server,query-optimization,Sql,Sql Server,Query Optimization,我有以下疑问 DECLARE @userId INT DECLARE @siteId INT SET @siteId = -1 SET @userId = 1828 SELECT a.id AS alertId, a.location_id, a.alert_type_id, a.event_id, a.user_id, a.site_id, a.accept

我有以下疑问

DECLARE @userId INT DECLARE @siteId INT SET @siteId = -1 SET @userId = 1828 SELECT a.id AS alertId, a.location_id, a.alert_type_id, a.event_id, a.user_id, a.site_id, a.accepted_by FROM alerts AS a JOIN alert_types AS ats ON a.alert_type_id = ats.id JOIN events AS tr ON a.event_id = tr.event_id WHERE tr.end_Time IS null AND tr.status_id = 0 AND ats.code = 'E' AND a.site_id in (SELECT * FROM dbo.udf_get_event_sitelist(@siteId, @userId)) 运行此查询需要5到17秒,但是在许多情况下,函数dbo.udf_get_event_sitelist@siteId,@userId不返回任何行,因此查询将找不到任何数据


如何强制SQL Server首先执行用户定义的函数。我很感激我可以将查询重写为一个存储过程并首先执行子选择,但是如果可能的话,我希望在一个SQL语句中执行它。

您可以将udf\u get\u event\u sitelist的结果选择到一个表变量中,并且仅在@rowcount>0的情况下继续执行大查询,修改您的UDF以只返回站点ID,因为我猜您不需要所有*列

SELECT * FROM dbo.udf_get_event_sitelist(@siteId, @userId)


使用内联函数时存在的问题是,可以为SELECT中返回的每一行重新计算内联函数。这意味着,如果SELECT语句返回100行,那么该函数可以执行100次


如果您认为Sambo99需要索引,那么应该真正遵循Sambo99的建议,将其提取到表变量或临时表中

将FROM表作为函数的结果集,并将其他表连接到它

DECLARE @userId INT  
DECLARE @siteId INT

SET @siteId = -1  
SET @userId = 1828  

SELECT  a.id AS alertId,  
        a.location_id,  
        a.alert_type_id,  
        a.event_id,  
        a.user_id,  
        a.site_id,  
        a.accepted_by  
FROM    (SELECT * FROM dbo.udf_get_event_sitelist(@siteId, @userId)) dt
JOIN    alerts AS a ON dt.site_id=a.site_id
JOIN    alert_types AS ats ON a.alert_type_id = ats.id 
JOIN    events AS tr ON a.event_id = tr.event_id 
WHERE   tr.end_Time IS null
AND     tr.status_id = 0
AND     ats.code = 'E'

你也可以发布你的UDF中的代码吗?请,我想你最好重新编写这个逻辑,可能作为子查询或CTE。我在这里没有看到存储过程,只是一个查询和一个函数。这些是内部联接、外部联接还是交叉联接。如果未提供联接类型,则默认为内部联接。通过编辑TingyJack以删除对存储过程的引用,此代码实际上是从SPI中提取的。假设UDF仅返回一列,否则这将无效?我同意,如果指定了列,会更清晰,但如果随后修改UDF以返回多个列,则可以防止查询被破坏。这不仅会更清晰,而且会鼓励更好的实践。鉴于缺少指定的连接类型,这无疑是一件好事。始终指定隐式连接类型是否被视为良好实践?我知道内部联接是默认类型,但我没有指定联接类型,因为我需要默认类型。同样地,我很少像暗示的那样使用升序排序。与其把它留给下一位读者的所有f'ups之母,不如说它更好。默认值已知会发生更改,但可能不是这种情况。我假设,由于我没有将子查询与外部查询关联,SQL Server将首先评估该条件,就像许多其他数据库引擎一样。我猜我的假设是错误的。它可能以任何一种方式发生,所以盲目地说一种方式或另一种方式就是假设优化器将要采取的计划。我认为在任何情况下,无论哪种方式都最好是明确的。谢谢迈克。我自己刚刚得到了同样的解决方案,但还没有写出来。出于兴趣,这将大多数查询所用的时间从5-15秒减少到了次秒
DECLARE @userId INT  
DECLARE @siteId INT

SET @siteId = -1  
SET @userId = 1828  

SELECT  a.id AS alertId,  
        a.location_id,  
        a.alert_type_id,  
        a.event_id,  
        a.user_id,  
        a.site_id,  
        a.accepted_by  
FROM    (SELECT * FROM dbo.udf_get_event_sitelist(@siteId, @userId)) dt
JOIN    alerts AS a ON dt.site_id=a.site_id
JOIN    alert_types AS ats ON a.alert_type_id = ats.id 
JOIN    events AS tr ON a.event_id = tr.event_id 
WHERE   tr.end_Time IS null
AND     tr.status_id = 0
AND     ats.code = 'E'