Как заставить SQL Server выполнить запрос в определенном порядке - PullRequest
3 голосов
/ 13 марта 2009

У меня есть следующий запрос

    
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, если это возможно.

Ответы [ 4 ]

4 голосов
/ 13 марта 2009

сделать из таблицы "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'
3 голосов
/ 13 марта 2009

Вы можете выбрать результаты udf_get_event_sitelist в табличную переменную и выполнить большой запрос, только если @@ rowcount> 0

2 голосов
/ 13 марта 2009

Проблема, с которой вы сталкиваетесь при использовании встроенных функций, заключается в том, что они могут быть переоценены для каждой строки, возвращаемой в SELECT. Это означает, что если инструкция SELECT возвращает 100 строк, то функция может быть выполнена 100 раз.

Вы должны действительно следовать совету Sambo99 и извлекать его в табличную переменную (или временную таблицу, если вы считаете, что ей нужны индексы).

0 голосов
/ 13 марта 2009

Кроме того, измените свой UDF так, чтобы он возвращал только site_ID, так как я предполагаю, что вы не используете все (*) столбцы

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

до

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