0

在这个查询中,我在下面的查询中调用了一个函数“fnGetPoolWinner”2-3 次,我认为这会减慢它的性能或多个 case 语句是原因。

大约需要时间 00:01:39。

我已经尝试过在表中创建索引和创建公用表表达式然后使用该查询等选项,但没有找到任何解决方案来减少时间。

DECLARE @TournamentId INT = 1

DECLARE @TournamentName AS NVARCHAR(MAX)

SELECT @TournamentName = TournamentName FROM Tournaments WHERE  TournamentId = @TournamentId


    SELECT 
    (SELECT CustomerIds FROM DBO.fnGetPoolWinner(SET_1.BracketBettingAmount,@TournamentId,
    (CASE
        WHEN SET_1.GAMES= 63
        THEN 1
        WHEN SET_1.GAMES= 31
        THEN 2
        WHEN SET_1.GAMES= 15
        THEN 3
        ELSE 0
    END))) AS [AccountNumber],
    @TournamentName AS TournamentName,
    (CASE
        WHEN SET_1.GAMES= 63
        THEN 'GENERAL POOL ROUND OF 64 $'+CAST(CAST(SET_1.BracketBettingAmount AS INT) AS NVARCHAR)+''
        WHEN SET_1.GAMES= 31
        THEN 'GENERAL POOL ROUND OF 32 $'+CAST(CAST(SET_1.BracketBettingAmount AS INT) AS NVARCHAR)+''
        WHEN SET_1.GAMES= 15
        THEN 'GENERAL POOL SWEET 16 $'+CAST(CAST(SET_1.BracketBettingAmount AS INT) AS NVARCHAR)+''
        ELSE ''
    END) AS [PoolName],
    (SELECT BracketNames FROM DBO.fnGetPoolWinner(SET_1.BracketBettingAmount,@TournamentId,
    (CASE
        WHEN SET_1.GAMES= 63
        THEN 1
        WHEN SET_1.GAMES= 31
        THEN 2
        WHEN SET_1.GAMES= 15
        THEN 3
        ELSE 0
    END))) AS GroupEntries,
    'Public' AS Access,
    COUNT(SET_1.BracketId) AS Members, 
    COUNT(SET_1.BracketId)*SET_1.BracketBettingAmount AS CurrentPoolPrize, 
    (SELECT WinnerNames FROM DBO.fnGetPoolWinner(SET_1.BracketBettingAmount,@TournamentId,
    (CASE
        WHEN SET_1.GAMES= 63
        THEN 1
        WHEN SET_1.GAMES= 31
        THEN 2
        WHEN SET_1.GAMES= 15
        THEN 3
        ELSE 0
    END))) AS WinnersName,
    (CASE
        WHEN SET_1.GAMES= 63
        THEN 1
        WHEN SET_1.GAMES= 31
        THEN 2
        WHEN SET_1.GAMES= 15
        THEN 3
        ELSE 0
    END) AS RoundId,
    SET_1.BracketBettingAmount AS BettingAmount
    FROM
        (SELECT BR.BracketId,
            BracketBettingAmount,
            (SELECT COUNT(1) FROM BracketPredictions AS BP WHERE BP.BracketPredictionBracketId =BR.BracketId) AS GAMES
        FROM Brackets AS BR WHERE BR.BracketTournamentId = @TournamentId AND BR.IsDeleted = 0) SET_1 WHERE SET_1.GAMES > 0
    GROUP BY SET_1.BracketBettingAmount, SET_1.GAMES HAVING SET_1.BracketBettingAmount IN (1,5,10,25)
4

2 回答 2

0

试试这个,未经测试

DECLARE @TournamentId INT = 1

    with SET_1 as (

      SELECT BR.BracketId, BracketBettingAmount as BettingAmount, W.GAMES, TN.TournamentName,
             case W.GAMES 
             WHEN 63 THEN 1
             WHEN 31 THEN 2
             WHEN 15 THEN 3
             ELSE 0 END as IDGAME,

             CASE W.GAMES
             WHEN 63 THEN 'GENERAL POOL ROUND OF 64 $'+CAST(CAST(BracketBettingAmount AS INT) AS NVARCHAR)
             WHEN 31 THEN 'GENERAL POOL ROUND OF 32 $'+CAST(CAST(BracketBettingAmount AS INT) AS NVARCHAR)
             WHEN 15 THEN 'GENERAL POOL SWEET 16 $'   +CAST(CAST(BracketBettingAmount AS INT) AS NVARCHAR)
             ELSE '' END AS PoolName,

             TN.TournamentId

             FROM Brackets AS BR 
             cross apply
             (
                SELECT COUNT(*) GAMES FROM BracketPredictions AS BP WHERE BP.BracketPredictionBracketId =BR.BracketId
             ) W

             inner join Tournaments TN on BR.BracketTournamentId=TN.TournamentId

             WHERE BR.IsDeleted = 0 and BracketBettingAmount IN (1,5,10,25) and W.GAMES>0 and TN.TournamentId = @TournamentId


    ),

    NbBracketId as ( select NbBracketId, count(*) Nb from SET_1 group by NbBracketId) 


    SELECT 
    Y.CustomerIds AccountNumber, X.TournamentName, X.PoolName, Y.BracketNames AS GroupEntries, 'Public' AS Access,
    Z.NB AS Members, Z.NB*X.BettingAmount AS CurrentPoolPrize, Y.WinnerNames, X.IDGAME AS RoundId, X.BettingAmount
    FROM SET_1 X 
    outer apply DBO.fnGetPoolWinner(SET_1.BracketBettingAmount, SET_1.TournamentId, SET_1.IDGAME) as Y
    inner join NbBracketId Z on X.BracketId=Z.BracketId
于 2017-06-02T06:04:42.773 回答
0

DBO.fnGetPoolWinner 可以自行优化。

试试这个方法,

DECLARE @TournamentId INT = 1
DECLARE @TournamentName AS NVARCHAR(MAX)
SELECT @TournamentName = TournamentName FROM Tournaments WHERE  TournamentId = @TournamentId
select @TournamentName TournamentName,
CustomerIds AS [AccountNumber]
,(CASE
        WHEN SET_1.GAMES= 63
        THEN 'GENERAL POOL ROUND OF 64 $'+CAST(CAST(SET_1.BracketBettingAmount AS INT) AS NVARCHAR)+''
        WHEN SET_1.GAMES= 31
        THEN 'GENERAL POOL ROUND OF 32 $'+CAST(CAST(SET_1.BracketBettingAmount AS INT) AS NVARCHAR)+''
        WHEN SET_1.GAMES= 15
        THEN 'GENERAL POOL SWEET 16 $'+CAST(CAST(SET_1.BracketBettingAmount AS INT) AS NVARCHAR)+''
        ELSE ''
    END) AS [PoolName]
    ,ca.BracketNames as GroupEntries
     'Public' AS Access,
    COUNT(SET_1.BracketId) AS Members, 
    COUNT(SET_1.BracketId)*SET_1.BracketBettingAmount AS CurrentPoolPrize
    ,WinnerNames  as WinnersName
    , (CASE
        WHEN SET_1.GAMES= 63
        THEN 1
        WHEN SET_1.GAMES= 31
        THEN 2
        WHEN SET_1.GAMES= 15
        THEN 3
        ELSE 0
    END) AS RoundId,
    SET_1.BracketBettingAmount AS BettingAmount
 FROM
       (SELECT BR.BracketId,
            BracketBettingAmount,
            (SELECT COUNT(1) FROM BracketPredictions AS BP WHERE BP.BracketPredictionBracketId =BR.BracketId) AS GAMES
        FROM Brackets AS BR WHERE BR.BracketTournamentId = @TournamentId AND BR.IsDeleted = 0) SET_1 
        WHERE SET_1.GAMES > 0
    GROUP BY SET_1.BracketBettingAmount, SET_1.GAMES 
    HAVING SET_1.BracketBettingAmount IN (1,5,10,25)

    cross apply(SELECT CustomerIds,BracketNames,WinnerNames
     FROM DBO.fnGetPoolWinner(SET_1.BracketBettingAmount,@TournamentId,
    (CASE
        WHEN SET_1.GAMES= 63
        THEN 1
        WHEN SET_1.GAMES= 31
        THEN 2
        WHEN SET_1.GAMES= 15
        THEN 3
        ELSE 0
    END)) )ca
于 2017-06-02T08:47:13.340 回答