Share via

Poor database performance

Sam 1,476 Reputation points
2020-12-31T07:26:24.173+00:00

Hi All,

We are seeing serious I/O contentions issues on one of our database called "MarketingDB".
Looking for some suggestions on how we can improve I/O demands for this database. Enabled Instant file initialization for data files to get some performance gain.
All data files are in one drive and log file is in a separate drive. Excluded Antivirus scans on all SQL Folders.
Formatted drives with 64k blocksize.
We tried archiving some data but reverted back. Since database is big, the deletes are taking a lot of time and ending up filling up the txn log file and we have a lot of LOB data types inside the tables.
We tried with batch deletes as well nothing but major improvements.
If the database files are not equi-sized. Anyone share thoughts of equi-sizing all the data files . We have a dedicated file for index data file.
The "Marketing_data" data file is becoming a HOT SPOT very frequently. What is the approach to distribute the data within the file into separate filegroups. What approach should be taken to distribute the tables?
Do we need to collect table sizes and distribute them as all big tables into one data file and all small tables into separate data file in a separate drive? what are the best practices ? partitioning ? Please share your thoughts.
52407-markettingdb.jpg

Autogrowth settings

====================

data files autogrowth 100MB , Unrestricted growth
log file autogrow by 1GB, unrestricted.

Best Regards,
Sam

SQL Server | Other

Answer accepted by question author
  1. David Browne 111 Reputation points Microsoft Employee
    2021-01-09T17:43:56.187+00:00

    You're getting about 7ms/read on a 6TB database with lots of IO, which is reasonable. Do you have an actual problem or just noticing the IO wait time? This might be acceptable, but you're probably a bit under-sized from an IO and VM point-of-view. Nothing wrong with that so long as your performance is acceptable and you can perform maintenance tasks in a reasonable time frame. But everything is harder and takes longer when you're running on under-sized infrastructure.

    Using Premium SSDs. It is an Azure Win server 2019 VM.

    How many disks and what SKU? Are they in a Storage Space (eg managed by the Azure SQL Server resource blade) or mounted individually?

    how we can improve I/O demands for this database.

    There's nothing you can do with the file and filegroup design that will make a difference. And moving tables between filegroups won't help either.

    From an infrastructure point-of-view add more disks and/or increase the VM size to provide more cache memory and possibly space for buffer pool extensions.

    Each P30 disk you add gives you 5000IOPS or 200MB/sec of additional throughput in addition to 1TB of usable space. So storage provisioning in Azure isn't just about the size of your database. You may need 20TB of space to get the performance you want on a 5TB database.

    But before you do that, evaluate whether some of your large tables can be compressed using PAGE or Columnstore compression, or your queries can be optimized to not have to read so much data. As I might have said once or twice before, turn on the Query Store. You will want to look at queries driving IO, both Logical Reads and Physical Reads (including Read-Ahead Reads).

    2 people found this answer helpful.

3 additional answers

Sort by: Most helpful
  1. Erland Sommarskog 133.7K Reputation points MVP Volunteer Moderator
    2021-01-11T22:10:15.11+00:00

    Yes Erland. Its an Azure VM. Here mainly I am looking for possible tuning opportunities to reduce I/O. Things like partitioning, archiving, or distributing data across multiple equi-sized data files etc...

    First of all, it is worth repeating what David said: Bigger disks will give you better throughput. That is how it works in Azure.

    When it comes to improving performance, David gave some tips, but we cannot really answer out of the blue. You need to analyse what is behind this high I/O. You also need to determine whether it is reads or writes you want to trim down. Adding indexes can reduce reads significantly - but it makes writes more expensive.

    David suggested that archiving data could help. Ideally, it should not matter. It is going to help if there are lot of scans that trawls through that old data without finding anything. With the old data out of the way, those scans will be faster. But they will still be scans. That said, archiving can still be a good idea, because it will reduce your backup times, and your backups will be easier to manage.

    Filegroups or partitioning - I agree with David. That's a non-starter.

    David also gave another great tip: Query Store. My experience is that in the end what pays off is to fix bad queries - by rewriting them or adding indexes. When I work with a new client that has performance issues, I always ask them to enable Query Store and extract data and send me.

    1 person found this answer helpful.

  2. Erland Sommarskog 133.7K Reputation points MVP Volunteer Moderator
    2021-01-05T22:19:03.457+00:00

    That data does not look too good. However, that is since the machine was last rebooted. What I usually do is that I schedule this query to run every 10-20 seconds and then compute the delta. When I can look io_write_stall_ms / io_num_of_writes to get the stall time.

    This is likely to reveal even higher peaks, but you will also see when they occur. I would guess the slowest response time occurs during disk rebuilds.

    You said these were local disks. What sort of? Spinning? SSD? NVMe? USB? :-)

    1 person found this answer helpful.

  3. AmeliaGu-MSFT 14,011 Reputation points Microsoft External Staff
    2021-01-01T03:16:13.12+00:00

    Hi @Sam ,
    Could you please share us more information about the I/O Performance?
    You can use sys.dm_io_virtual_file_stats which returns I/O statistics for data and log files to monitor I/O bottlenecks:

    SELECT   
    cast(DB_Name(a.database_id) as varchar) as Database_name,  
    b.physical_name, *   
    FROM    
    sys.dm_io_virtual_file_stats(null, null) a   
    INNER JOIN sys.master_files b ON a.database_id = b.database_id and a.file_id = b.file_id  
    ORDER BY Database_Name  
    

    You also can use Performance Monitor to capture statistics about I/O usage. The following counters are helpful to see if there is a bottleneck:

    • Avg. Disk sec/Read. The value of Avg. Disk sec/Read >20ms is bad.
    • Avg. Disk sec/Write The value of Avg. Disk sec/Read >20ms is bad.
    • Avg. Disk sec/Transfer If the values of this counter are consistently above 15-20 ms. then you need to take a look at the issue further.

    In addition, missing indexes, poorly written queries, fragmentation or out of date statistics can also cause slow I/O performance.
    For more information, please refer to Slow I/O - SQL Server and disk I/O performance and I/O troubleshooting which could help.
    Best Regards,
    Amelia


    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.