我正在尝试为我们公司创建一个查看子资产价格的视图。
我在视图中创建一个临时表,希望让程序运行得更快。但它不起作用。查询仍然超级慢......任何人都可以帮助我改进我的查询,或者你有蚂蚁建议是什么导致查询运行缓慢?感谢。
该计划旨在实施: - 如果新订单违反了子订单规则 - 如果订单确认违反了子便士规则 - 当新订单和订单确认价格不相等时
•系统中只能包含正确小数/舍入的订单 - (订单价格)
/*
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
答案 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中应该避免条件,在插入表格之前更好地转换和转换数据以点亮查询