SQL查询很慢

时间:2018-01-02 21:22:57

标签: sql database view

我正在尝试为我们公司创建一个查看子资产价格的视图。

我在视图中创建一个临时表,希望让程序运行得更快。但它不起作用。查询仍然超级慢......任何人都可以帮助我改进我的查询,或者你有蚂蚁建议是什么导致查询运行缓慢?感谢。

该计划旨在实施: - 如果新订单违反了子订单规则 - 如果订单确认违反了子便士规则 - 当新订单和订单确认价格不相等时

•系统中只能包含正确小数/舍入的订单 - (订单价格)

/*
    price < $ 0.01    6 decimal places
    price< $1.00     4 decimal places
    price>=  $1.00  2 decimal places
    price>= $100,000   1 decimal places
*/


WITH PRICE (newOrderPrice, NewOrderprice, newTransactionGUID, newMsgText,ackOrderPrice,AckOrderprice,ackTransactionGUID,ackMsgText)
     AS (
         SELECT  
            --remove the trailing 0 in price
            REVERSE(SUBSTRING(reverse(NewOrderprice), PATINDEX('%[1-9.]%', reverse(NewOrderprice)), len(NewOrderprice) - PATINDEX('%[1-9.]%', reverse(NewOrderprice)) + 1))  AS newOrderPrice
            , NewOrderprice
            , newTransactionGUID
            , newMsgText
            , REVERSE(SUBSTRING(reverse(AckOrderprice), PATINDEX('%[1-9.]%', reverse(AckOrderprice)), len(AckOrderprice) - PATINDEX('%[1-9.]%', reverse(AckOrderprice)) + 1))  AS ackOrderPrice
            , AckOrderprice
            , ackTransactionGUID
            , ackMsgText

            FROM
            (
                SELECT    --make sure we get the price from transactiontext tag 44 is only numbers
                          --------------------new Order----------------------------------------------------------
                          LEFT(SUBSTRING(LscDP.dbo.ParseTransactionText(44,t.MsgText), PATINDEX('%[0-9.]%', LscDP.dbo.ParseTransactionText(44,t.MsgText)), 8000),
                          PATINDEX('%[^0-9.]%', SUBSTRING(LscDP.dbo.ParseTransactionText(44,t.MsgText), PATINDEX('%[0-9.]%',
                          LscDP.dbo.ParseTransactionText(44,t.MsgText)), 8000) + 'X') -1)  
                          AS NewOrderprice
                          , t.TransactionGUID AS newTransactionGUID
                          , t.MsgText AS newMsgText
                          -----------------ack order------------------------------------------------------------
                          ,LEFT(SUBSTRING(LscDP.dbo.ParseTransactionText(44,ack.MsgText), PATINDEX('%[0-9.]%', LscDP.dbo.ParseTransactionText(44,ack.MsgText)), 8000),
                          PATINDEX('%[^0-9.]%', SUBSTRING(LscDP.dbo.ParseTransactionText(44,ack.MsgText), PATINDEX('%[0-9.]%',
                          LscDP.dbo.ParseTransactionText(44,ack.MsgText)), 8000) + 'X') -1)  
                          AS AckOrderprice
                          , ack.TransactionGUID AS ackTransactionGUID
                          , ack.MsgText    AS ackMsgText
                FROM      LscDP..DailyTransactionText t
                          INNER JOIN  LscDP..DailyTransactionText ack
                                      ON t.Sender = ack.Sender
                                         AND t.Branch = ack.Branch
                                         AND t.BranchSeq = ack.BranchSeq
                                         and ack.MsgType = '1' 
                                         and t.MsgType = '0'
                          INNER JOIN LscDP..DailyOrders o
                                      ON t.TransactionGUID = o.TransactionGUID
                                         OR ack.TransactionGUID = o.TransactionGUID
                          LEFT JOIN AccountsEX..OutQueues oq
                                      ON o.Route = oq.OutQueue


                WHERE   
                        t.Symbol not like '%-%' -- exclude foreign symbols
                        AND LscDP.dbo.ParseTransactionText(167,t.MsgText) <> 'OPT'  --Exclude options
                        AND LscDP.dbo.ParseTransactionText(167,ack.MsgText) <> 'OPT'  --Exclude options
                        AND ISNULL(oq.QueueType, '') NOT IN ('DC','CL')
                        AND LscDP.dbo.ParseTransactionText(44,t.MsgText) <> ''
                        AND LscDP.dbo.ParseTransactionText(44,ack.MsgText) <> ''
                        AND LscDP.dbo.ParseTransactionText(44,t.MsgText) like '%.%'   --Only need verify the subdollar.
                        AND LscDP.dbo.ParseTransactionText(44,ack.MsgText) like '%.%'   --Only need verify the subdollar.
            ) X
           ) 


SELECT  
       CASE  WHEN 
                  ----------------------NEW-------------------------------------
                 ( --Price < 0.01 , 6 decimal max

                    CAST(newOrderPrice AS FLOAT) < 0.01 
                    AND (LEN(newOrderPrice) - PATINDEX('%.%',newOrderPrice)) <= 6
                 )
                OR
                 ( --Price < 1 , 4 decimal max

                    CAST(newOrderPrice AS FLOAT) < 1 
                    AND (LEN(newOrderPrice) - PATINDEX('%.%',newOrderPrice)) <= 4
                 ) 
                 OR
                 (  --Price >= 1 , 2 decimal max

                   CAST(newOrderPrice AS FLOAT) >= 1
                   AND (LEN(newOrderPrice) - PATINDEX('%.%',newOrderPrice)) <= 2
                  )
                 OR
                 (  --Price >= 100000 , 1 decimal max
                   CAST(newOrderPrice AS FLOAT) >= 100000
                   AND (LEN(newOrderPrice) - PATINDEX('%.%',newOrderPrice)) <= 1
                  )
                  ----------------------ACK-------------------------------------
                 OR
                 ( --Price < 0.01 , 6 decimal max

                    CAST(ackOrderPrice AS FLOAT) < 0.01 
                    AND (LEN(ackOrderPrice) - PATINDEX('%.%',ackOrderPrice)) <= 6
                  )
                 OR
                 ( --Price < 1 , 4 decimal max

                    CAST(ackOrderPrice AS FLOAT) < 1 
                    AND (LEN(ackOrderPrice) - PATINDEX('%.%',ackOrderPrice)) <= 4
                 ) 
                 OR
                 (  --Price >= 1 , 2 decimal max

                   CAST(ackOrderPrice AS FLOAT) >= 1
                   AND (LEN(ackOrderPrice) - PATINDEX('%.%',ackOrderPrice)) <= 2
                  )
                 OR
                 (  --Price >= 100000 , 1 decimal max
                   CAST(ackOrderPrice AS FLOAT) >= 100000
                   AND (LEN(ackOrderPrice) - PATINDEX('%.%',ackOrderPrice)) <= 1
                  )
                  THEN 'Qualified'
                  WHEN  ISNULL(ackOrderPrice,'') <> ISNULL(newOrderPrice,'')
                  THEN 'NewAckPriceMismatch'
                  ELSE 'Violation'
                  END AS PriceVerify


       ,*



FROM  PRICE

2 个答案:

答案 0 :(得分:2)

找到你的问题:

AND price like '%.%'

通过使用通配符开始,您正在强制进行表扫描,这将提高性能。有几种方法可以在不制作SARG的情况下获得相同的结果。 Patindex将是我的推荐:

https://docs.microsoft.com/en-us/sql/t-sql/functions/patindex-transact-sql

答案 1 :(得分:1)

一般来说,带有%的Like条件会减慢查询速度,而parsetransactionText也听起来不那么快

AND price like '%.%'
    AND t.Symbol not like '%-%' -- exclude foreign symbols
                            AND LscDP.dbo.ParseTransactionText(167,MsgText) <> 'OPT'  --Exclude options

另外请管理尾随零,如下例所示 How to display two digits after decimal point in SQL Server

另一个重大错误是稍后从临时表结果中过滤,向上移动过滤器

WHERE   Price <> ''
        AND price like '%.%'   --Only need verify the subdollar.

为了减少临时表的大小

此外,如果可能的话,所有“后处理”都需要在临时表上向下移动,以便仅对较小的数据集执行

LEFT(SUBSTRING(LscDP.dbo.ParseTransactionText(44,MsgText), PATINDEX('%[0-9.]%', LscDP.dbo.ParseTransactionText(44,MsgText)), 8000),
                          PATINDEX('%[^0-9.]%', SUBSTRING(LscDP.dbo.ParseTransactionText(44,MsgText), PATINDEX('%[0-9.]%',
                          LscDP.dbo.ParseTransactionText(44,MsgText)), 8000) + 'X') -1)  
                          AS price

一般情况下,在你的选择中重新排列数据,并且在sql中应该避免条件,在插入表格之前更好地转换和转换数据以点亮查询