Question

J'ai la requête suivante

    
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))

L'exécution de cette requête prend entre 5 et 17 secondes. Toutefois, dans de nombreuses circonstances, la fonction dbo.udf_get_event_sitelist (@siteId, @userId) ne renvoie aucune ligne. Par conséquent, la requête ne trouve aucune donnée.

Comment puis-je forcer SQL Server à exécuter d'abord la fonction définie par l'utilisateur? J'apprécie le fait que je puisse réécrire la requête dans une procédure stockée et effectuer la sous-sélection en premier, mais j'aimerais toutefois le faire si possible dans une seule instruction SQL.

Était-ce utile?

La solution

créer le " FROM " table le jeu de résultats de la fonction et y associe les autres tables

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'

Autres conseils

vous pouvez sélectionner les résultats de udf_get_event_sitelist dans une variable de table et ne poursuivre que la grande requête si @@ rowcount > 0

Le problème que vous rencontrez lors de l’utilisation de fonctions inline est qu’elles peuvent être réévaluées pour chaque ligne renvoyée dans SELECT. Cela signifie que si l'instruction SELECT renvoie 100 lignes, la fonction peut être exécutée 100 fois.

Vous devriez vraiment suivre le conseil de Sambo99 et l'extraire dans une variable de table (ou dans une table temporaire si vous pensez qu'elle a besoin d'index).

Modifiez également votre fichier UDF pour ne renvoyer que le site_ID car je suppose que vous ne devez pas supprimer toutes les colonnes (*)

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

à

SELECT site_id FROM dbo.udf_get_event_sitelist(@siteId, @userId)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top