patternsqlMinor
SQL database performance optimization
Viewed 0 times
sqloptimizationdatabaseperformance
Problem
We have a write-heavy SQL database (SQL Server 2008) and the insert speed decreases after some time. I read these similar questions: Sql insert speed up, SQL: What is slowing down INSERTs if not CPU or IO? and Speed up INSERTs.
Also, I read this post about how to analyze SQL Server performance which helped me to know how to find bottlenecks (for example, by querying
First, I started with querying the
Next, I used
Then I used
Some more info:
-
Using
80336 and 70672 respectively.
-
One of our most busy tables is
transactions) with NO TRIGGERS, NO CON
Also, I read this post about how to analyze SQL Server performance which helped me to know how to find bottlenecks (for example, by querying
sys.dm_exec_requests and sys.dm_os_wait_stats), but still I have difficulties in interpreting the query results and fixing the problem.First, I started with querying the
sys.dm_exec_requests which only returned one session id (select query) with status "running" (i.e., I found NO SUSPENDED SESSIONS). So, if nothing has blocked my insert, why does it become slow?Next, I used
sys.dm_os_wait_stats to check statistics about all wait types. The result showed that LATCH_EX, CXPACKET AND PAGEIOLATCH_SH had the most wait_time (694379 ms, 310364 ms and 308335 ms respectively). Then I used
sys.dm_os_latch_stats to find the most prevalent latch type which in my case was ACCESS_METHODS_DATASET_PARENT.- First of all, I don't know how to find the query related to each session_id in the results of querying
sys.dm_exec_requests.
- Secondly, what numbers of wait-time (in
sys.dm_os_wait_stats) should be considered as high? And if the above mentioned numbers (results of sys.dm_os_wait_stats) are high, how can I decrease them?
- As far as I understand,
ACCESS_METHODS_DATASET_PARENTis related to parallelism and one of the solutions I've found was reducing the degree of parallelism. Is that right?
- In MySQL, there are some tunning settings which could be done right after installation (e.g., increasing innodb buffer pool size), is there something similar in SQL Server?
Some more info:
-
Using
sys.dm_db_index_usage_stats, number of reads and writes are80336 and 70672 respectively.
-
One of our most busy tables is
trans_all (showing all paymentstransactions) with NO TRIGGERS, NO CON
Solution
There are many factors that could be causing this slow down of inserts as you have described.
Something that I do not see in your information is the Database / Table size that the inserts are going into. As the table grows, the longer your inserts will take due to table size, fragmentation and writing the same data to your indexes.
The DM queries you are running have given you some good information. I would also recommend using Brent Ozar's toolkit. Link
I would suggest you use SP_BlitzIndex and SP_BlitzCache. These will give you another view of what is actually happening in the database and what the insert queries you are running are doing at that time.
I would also check when the last time a DBCC CHECKDB was run and also when you last rebuilt your indexes and statistics.
Thanks for the updates, see below:
Some more info:
Not a huge amount of read/writes so I'm not too concerned.
Do you know when the last time the trans_all index was rebuilt? If you only have one covering index and many inserts, it will take longer each time when inserting data to it if it is out of date. Below is a query to check fragmentation on your database tables:
UPDATE 1:
MAX DOP settings can affect your query run time, but I can't be sure it is doing so without seeing the query you are using and then looking at the estimated plan results to see what SQL server is using. There are two statistics to use to find out how the query is affected when adjusting the MAX DOP.
Here is some information by Kendra Little over at Brent Ozar on using these to give you guidelines.
tsql-measure-performance-improvements
and
q-can-high-maxdop-make-a-query-slower
UPDATE 2:
I would recommend increasing your Log size if it is 98% full. Either add another trans log or increase it. You might also look at TEMP_DB and see what it is doing because SQL using that as a dumping ground for many things.
Empty space isn't really an issue unless you are out of room to grow. It is just telling you how much room is left until the next auto grow.
Something that I do not see in your information is the Database / Table size that the inserts are going into. As the table grows, the longer your inserts will take due to table size, fragmentation and writing the same data to your indexes.
The DM queries you are running have given you some good information. I would also recommend using Brent Ozar's toolkit. Link
I would suggest you use SP_BlitzIndex and SP_BlitzCache. These will give you another view of what is actually happening in the database and what the insert queries you are running are doing at that time.
I would also check when the last time a DBCC CHECKDB was run and also when you last rebuilt your indexes and statistics.
Thanks for the updates, see below:
Some more info:
Not a huge amount of read/writes so I'm not too concerned.
Do you know when the last time the trans_all index was rebuilt? If you only have one covering index and many inserts, it will take longer each time when inserting data to it if it is out of date. Below is a query to check fragmentation on your database tables:
Use
GO
SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName,
ind.name AS IndexName, indexstats.index_type_desc AS IndexType,
indexstats.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats
INNER JOIN sys.indexes ind
ON ind.object_id = indexstats.object_id
AND ind.index_id = indexstats.index_id
WHERE indexstats.avg_fragmentation_in_percent > 30
ORDER BY indexstats.avg_fragmentation_in_percent DESCUPDATE 1:
MAX DOP settings can affect your query run time, but I can't be sure it is doing so without seeing the query you are using and then looking at the estimated plan results to see what SQL server is using. There are two statistics to use to find out how the query is affected when adjusting the MAX DOP.
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
GOHere is some information by Kendra Little over at Brent Ozar on using these to give you guidelines.
tsql-measure-performance-improvements
and
q-can-high-maxdop-make-a-query-slower
UPDATE 2:
I would recommend increasing your Log size if it is 98% full. Either add another trans log or increase it. You might also look at TEMP_DB and see what it is doing because SQL using that as a dumping ground for many things.
Empty space isn't really an issue unless you are out of room to grow. It is just telling you how much room is left until the next auto grow.
Code Snippets
Use <Database>
GO
SELECT OBJECT_NAME(ind.OBJECT_ID) AS TableName,
ind.name AS IndexName, indexstats.index_type_desc AS IndexType,
indexstats.avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) indexstats
INNER JOIN sys.indexes ind
ON ind.object_id = indexstats.object_id
AND ind.index_id = indexstats.index_id
WHERE indexstats.avg_fragmentation_in_percent > 30
ORDER BY indexstats.avg_fragmentation_in_percent DESCSET STATISTICS IO ON;
SET STATISTICS TIME ON;
GOContext
StackExchange Database Administrators Q#155868, answer score: 2
Revisions (0)
No revisions yet.