November 5, 2021 at 2:30 pm
This query runs very slow at times and very fast at time.
What could cause this behavior?
i checked the slowness is coming from auditLog table. Its a big table as it stores audit records.
But still cant figure out why its very slow at times.
select * from
(
SELECT coitem.[ship_site]
,custaddr.[name]
,coitem.[co_num]
,coitem.[co_line]
,coitem.[item]
,coitem.[description]
,coitem.[qty_ordered]
,coitem.[due_date]
,(coitem.[Price] * coitem.qty_ordered ) AS ExtPrice
,co.[taken_by]
,co.[order_date]
,ISNULL(AuditLog.CreateDate, SalesSignOff.CreateDate ) AS SalesEnggSignOffDate
,item.family_code
,item.Uf_EngRelease AS EngReleaseStatus
,coitem.Uf_COLinePlanningNotes
FROM coitem(NOLOCK)
JOIN co (NOLOCK) ON co.co_num = coitem.co_num
JOIN custaddr (NOLOCK) ON custaddr.cust_num = co.cust_num AND custaddr.cust_seq = 0
JOIN item (NOLOCK) ON item.item = coitem.item
LEFT OUTER JOIN dbo.AuditLog (NOLOCK) ON dbo.AuditLog.RecordDate > co.CreateDate AND MessageType = 10474 AND KeyValue = (co.co_num + '-' + CAST(coitem.co_line AS VARCHAR(10)) + '-0' ) AND NewValue = item.item AND OldValue LIKE 'new%'
LEFT OUTER JOIN dbo.AuditLog (NOLOCK) SalesSignOff
ON SalesSignOff.RecordDate >= co.CreateDate
AND SalesSignOff.MessageType = 10081
AND SalesSignOff.KeyValue = co.co_num
AND SalesSignOff.OldValue = 'P' AND SalesSignOff.NewValue = 'O'
WHERE co.stat = 'O' AND coitem.stat = 'P' and coitem.ship_site = 'Oshk'
) aa
November 5, 2021 at 2:34 pm
i checked the slowness is coming from auditLog table. Its a big table as it stores audit records.
November 5, 2021 at 2:54 pm
What indexes do you have on that table?
Looks like an index on ( MessageType, NewValue, KeyValue, RecordDate ) INCLUDE ( CreateDate, OldValue )
might be useful for this query.
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
November 5, 2021 at 3:41 pm
Good info above.
Depending on plans as well, you could have parameter sniffing if parameters change. Or a plan could get ejected and a new one come in. If you have query store, you should be able to see if plans change.
November 5, 2021 at 7:10 pm
But still cant figure out why its very slow at times.
It's probably because the triggers that feed it are written incorrectly as some form of dynamic SQL that materialize the INSERTED and DELETED tables. I've run into this exact Audit table dozens of times and use to have the url from the article from this very forum that suggested it on the bulls-eye of a dart board.
Check the triggers that feed the audit table and see if I'm right.
The other part of the issue is may be that the data you're looking for is no longer in cache and so it has to load the data to query it.
The worse part about the "columnar" audit tables is that any non-clustered indexes on them are going to be nearly as big as the clustered indexes and they're going to need to be maintained in order to get any speed out of them because they're going to fragment like the dickens.
My other recommendation is to not use a join to the audit table along with all the other joins. Store the data from the other tables into a Temp Table and then go lookup the data you need from the audit table. Divide'n'Conquer methods can help quite a bit here. Not always, but frequently.
--Jeff Moden
Change is inevitable... Change for the better is not.
November 5, 2021 at 8:01 pm
This is not going to allow index usage in the join: AND KeyValue = (co.co_num + '-' + CAST(coitem.co_line AS VARCHAR(10)) + '-0' )
Further to @JeffModen's idea - create a temp table from the other tables, combining co.co_num, coitem.co_line into a pre-defined KeyValue column in the temp table, then join using that predefined column.
I also noticed that you are joining to AuditLog twice - and in both cases you have an open-ended range for RecordDate. It might be a good idea to figure out the date range you want to search for matching records.
Looking at what you are pulling - it might be a better option to use OUTER APPLY to get the audit records. If you are expecting only a single row to be returned from the audit log for each LEFT OUTER JOIN - then a TOP 1 with an ORDER BY on the RecordedDate might even be better...not sure though.
Jeffrey Williams
“We are all faced with a series of great opportunities brilliantly disguised as impossible situations.”
― Charles R. Swindoll
How to post questions to get better answers faster
Managing Transaction Logs
November 6, 2021 at 5:03 am
This is not going to allow index usage in the join: AND KeyValue = (co.co_num + '-' + CAST(coitem.co_line AS VARCHAR(10)) + '-0' )
SQL can use an index for the KeyValue column, it just can't do an index seek for it. SQL can still add a predicate to compare that column as long as the column appears somewhere in the index.
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply