SQL Server Stored procedure runs much slower than query

k7fdbhmy  于 2023-10-15  发布在  其他
关注(0)|答案(2)|浏览(111)

I have a stored procedure which creates a 2x2 table for an odds ratio. A rudimentary odds ratio table looks like:

EDIT - this query finally did finish and it did return the correct answer after two minutes and 32 separate calls to the function. I can't see why this is running recursively, any ideas, SO?

A - only records that satisfy both thing 1 and thing 2 go here
B - only records that satisfy thing 1 (people with thing 2 CANNOT go here)
C - only records that satisfy thing 2 (people with thing 1 CANNOT go here)
D - people with thing 1 OR thing 2 cannot go here

All of the cells in the table will be integers representing a population of people.

I was trying to learn some new syntax and decided to use intersect and except . I wanted to make the thing 1 and thing 2 s variables so I put the below query into a stored procedure.

CREATE PROC Findoddsratio (@diag1 NVARCHAR(5), 
                           @diag2 NVARCHAR(5)) 
AS 
    IF Object_id('tempdb..#temp') IS NOT NULL 
      DROP TABLE #temp 

    CREATE TABLE #temp 
      ( 
         squarenumber CHAR(1), 
         counts       FLOAT 
      ) 

    INSERT INTO #temp 
                (squarenumber, 
                 counts) 
    SELECT * 
    FROM   ( 
           --both + 
           SELECT 'a'                                    AS squareNumber, 
                  Cast(Count(DISTINCT x.counts)AS FLOAT) AS counts 
           FROM   (SELECT DISTINCT ic.patid AS counts 
                   FROM   icdclm AS ic 
                   WHERE  ic.icd LIKE @diag1 
                   INTERSECT 
                   SELECT DISTINCT ic.patid AS counts 
                   FROM   icdclm AS ic 
                   WHERE  ic.icd LIKE @diag2)x 
           UNION 
           --only 1+ 
           SELECT 'b', 
                  Count(DISTINCT x.counts) 
           FROM   (SELECT DISTINCT ic.patid AS counts 
                   FROM   icdclm AS ic 
                   WHERE  ic.icd LIKE @diag1 
                   EXCEPT 
                   SELECT DISTINCT ic.patid AS counts 
                   FROM   icdclm AS ic 
                   WHERE  ic.icd LIKE @diag2)AS x 
           UNION 
           --only 2+ 
           SELECT 'c', 
                  Count(DISTINCT x.counts) 
           FROM   (SELECT DISTINCT ic.patid AS counts 
                   FROM   icdclm AS ic 
                   WHERE  ic.icd LIKE @diag2 
                   EXCEPT 
                   SELECT DISTINCT ic.patid AS counts 
                   FROM   icdclm AS ic 
                   WHERE  ic.icd LIKE @diag1)AS x 
            UNION 
            --both - 
            SELECT 'd', 
                   Count(DISTINCT x.counts) 
            FROM   (SELECT DISTINCT ic.patid AS counts 
                    FROM   icdclm AS ic 
                    EXCEPT 
                    SELECT DISTINCT ic.patid AS counts 
                    FROM   icdclm AS ic 
                    WHERE  ic.icd LIKE @diag2 
                    EXCEPT 
                    SELECT DISTINCT ic.patid AS counts 
                    FROM   icdclm AS ic 
                    WHERE  ic.icd LIKE @diag1) AS x)y 

    --i used a pivot table to make the math work out easier 
    SELECT Round(Cast(( a * d ) / ( b * c ) AS FLOAT), 2) AS OddsRatio 
    FROM   (SELECT [a], 
                   [b], 
                   [c], 
                   [d] 
            FROM   (SELECT [squarenumber], 
                           [counts] 
                    FROM   #temp) p 
                   PIVOT ( Sum(counts) 
                         FOR [squarenumber] IN ([a], 
                                                [b], 
                                                [c], 
                                                [d]) ) AS pvt)t

ICDCLM is a table with a structure like patid=int, icd=varchar(5)

There are ~ one million rows in ICDCLM . When I run this query without making it a stored procedure, it runs in seconds. If I try to exec FindsOddsRation 'thing1%','thing2%' . It runs and runs, but never returns anything (> 2 minutes). What could be the difference in the stored procedure taking so long? SQL Server 2008 R2 fiddle here

q0qdq0h2

q0qdq0h21#

If you're running the same exact SQL as the stored procedure and the times are that different, your stored procedure is probably relying on metadata that is out of date. Try updating statistics or recompiling the stored procedure.

qeeaahzv

qeeaahzv2#

Before to change the procedure, be sure that the statistics are up to date. Also, check the actual execution plan (xml doc) of the Store procedure and look for the value of the parameters used to create the plan. Also Check Do a profiling for the parameters that were sniffed and the actual parameters, if the distribution of values or whatever you are pulling if way to different for those sets, then you can talk about parameter sniffing.

After updating statistics and recompiling the Store Procedure, check if the problem continue. You can play with the same set of parameters (the set that was sniffed and the one giving the problem).

相关问题