Shrinking a database...should I - sql

I have a database which is around 20GB in size but actually free space is around 17GB. This has happened because I have moved out quite a few audit tables that were large in size to another database altogether.
I mistakenly tried to perform a shrink database whilst in business hours but didn't realise the time it would take it to complete this so managed to stop it.
I've now done some research on this and I've read articles where shrinking a database shouldnt be done because it can cause "massive" index fragmentation. I'm no SQL guru but this does ring alarm bells.
People have suggested using a shrink with truncate only.
Are there any sql experts out there that can help me out with the right thing to do here??

Shrinking a database after you remove a large amount of data in a one-time operation is proper. You want to leave plenty of free space, as re-growing can be expensive. And you want to rebuild indexes after shrinking, to remove the fragmentation.
But here the database is only 20GB, so shrinking it won't really solve any problems. If you wanted to shrink it to 6GB or so, that would be fine. But I would just leave it at 20GB.

Related

What is using all my storage in SQL server

I have a SQL server database that according Properties => files, is using 47GB of disk space in the primary file group.
I am 99% sure my database is not this big.
I ran the query from this post https://www.mssqltips.com/sqlservertip/1177/determining-space-used-for-all-tables-in-a-sql-server-database/
and according to this my reserved space is only 1 GB, so how can my DB possibly be using this much space?
I have shrunk the log file but as I said above, it is the primary file that is this size
As per my comment: When a database file grows, it won't release space; most likely it got to 47GB at some point perhaps when you were doing a large load and you since deleted the data? Not releasing the space is intentional, and in fact shrinking your database is a dangerous path to go down unless you know what you're doing; as it'll easily cause things like fragmentation of your indexes.
You can find out how much space, and unused space, there is by using objects like sys.sp_spaceused; Which will detail the amount of free space in the unallocated space column.
As noted above, it's not advised you shrink the database unless you really must. Fragmentation will very likely occur during a shrink; which could have (significant) impacts on the performance of your database.
A database is made up of reserved space and of that a portion will be available space. As the db grows the available space gets smaller until an autogrowth is triggered. The autogrowth increments are set as a value or percentage. It is possible that when the database was initially created an initial value of 47023 was set. You can free up that available space back to the OS but you need to shrink the data file, not the log file, but just be cognizant of how your database is growing and how often those auto-growths are happening because there could be a performance compromise to doing that.
You may find it very useful to run two built in SSRS reports. To do so (in SQL Server Management Studio) right click on the database name and then ten selections down is a tab marked reports. Click on it and try the 'Disk Usager' report and the 'Disk Usage by Top Tables' report. They are very clear reports and you may be surprised at how large certain tables are.

What about performance of cursors,reindex and shrinking?

i am having recently came to know that sql server if i delete one column or modify it acquires space at backend so i need to reindex and shrink the database and i have done it and my datbase size reduced to
2.82 to 1.62
so its good like wise so now i am in a confusion
so in my mind many questions regarding this subject occurs pls help me about this one
1. So it is necessary to recreate indexes(refresh ) after particular interval
It is necessary to shrink database after particular time so performance will be up to date?
If above yes then what particular time should i refresh (Shrink) my database?
i am having no idea what should be done for disk spacing problem i am having 77000 records it takes 2.82gb dataspace which is not acceptable i am having two tables of that one only with one table nvarchar(max) so there should be minimum spaces to database can anyone help me on this one Thanks in advance
I am going to simplify things a little for you so you might want to read up about the things I talk about in my answer.
Two concepts you must understand. Allocated space vs free space. A database might be 2GB in size but it is only using 1GB so it has allocated 2GB with 1GB free space. When you shrink a database it removes the free space so free space should be about 0. Dont think smaller file size is faster. As you database grows it has to allocate space again. When you shrink the file and then it grows every so often it cannot allocate space in a contiguous fashion. This will create fragmentation of the files which slows you down even more.
With data files(.mdb) files this is not so bad but with the transaction log shrinking the log can lead to virtual log file fragmentation issues which can slow you down. So in a nutshell there is very little reason to shrink your database on a schedule. Go read about Virtual Log Files in SQL Server there are a lot of articles about it. This is a good article about shrink log files and why it is bad. Use it as a starting point.
Secondly indexes get fragmented over time. This will lead to bad performance of SELECT queries mainly but will also affect other queries. Thus you need to perform some index maintenance on the database. See this answer on how to defragment your indexes.
Update:
Well the time you rebuild indexes is not clear cut. Index rebuilds lock the index during the rebuild. Essentially they are offline for the duration. In your case it would be fast 77 000 rows is nothing for SQL server. So rebuilding the indexes will consume server resources. IF you have enterprise edition you can do online index rebuilding which will NOT lock the indexes but will consume more space.
So what you need to do is find a maintenance window. For example if your system is used from 8:00 till 17:00 you can schedule maintenance rebuilds after hours. Schedule this with SQL server agent. The script in the link can be automated to run.
Your database is not big. I have seen SQL server handle tables of 750GB without taking strain if the IO is split over several disks. The slowest part of any database server is not the CPU or the RAM but the IO pathways to the disks. This is a huge topic though. Back to your point you are storing data in NVARCHAR(MAX) fields. I assume this is large text. So after you shrink the database you see the size at 1,62GB which means that each row in your database is about 1,62/77 000 big or roughly 22Kb big. This seems reasonable. Export the table to a text file and check the size you will be suprised it will probably be larger than 1,62GB.
Feel free to ask more detail if required.

Speedup SQL Database Shrinking Process

I have to shrink and backup a database every week which is about 100+ GB of size.
Normally it takes 2-3 hours to shrink. This is quite frustrating especially when management wants this database to be deployed quickly.
My question is
1-Is there some way to shrink a huge database quickly.
2-Instead of shrinking, if I do a backup with shrink option enabled, does it do the same, like removing unnecessary pages.
Thanks
1: no, in generally you do not shrink "real" databases (of size). specially given that SQL Server backup will not back up pages in the database not used, so a backup of an empty 1000gb database is VERY small, it makes no sense to shrink. How you think people do real backups of IMPORTANT stuff (where you run a delta backup like every 15 minutes)? Generally do not use autogrow, do not use shrink on anything that has a large size.
2: moot as per 1. Do not shrink.
Why do you think you need to shrink the database in the first place? Btw., 100gb is quite small - things get runny once you hit 1000gb and larger.

How do I optimize table after delete many records

I deleted many records from my table but the DB size (Firebird) left the same. How do I decrease it?
I am looking for something similar to vacuum in PostgreS.
This is one of many pains of firebird.
Best and only effective and right way to do this - backup/restore your database using gbak
Firebird will occasionally run a sweep to remove the records from indexes etc., and regain the space for other use. In other words, as soon as the sweep has run, you will have the same performance as if the database file was smaller. You can enforce an immediate sweep, if that is what you are trying to do.
However, the size of the actual database will not shrink, no matter what, except if you do a backup and restore. If size is a problem, use the -USE_ALL_SPACE parameter for gbak, it will prevent that space is being reserved for future records, which will yield a smaller database.
From the official faq
Many users wonder why they don't get their disk space back when they
delete a lot of records from database.
The reason is that it is an expensive operation, it would require a
lot of disk writes and memory - just like doing refragmentation of
hard disk partition. The parts of database (pages) that were used by
such data are marked as empty and Firebird will reuse them next time
it needs to write new data.
If disk space is critical for you, you can get the space back by
doing backup and then restore. Since you're doing the backup to
restore right away, it's wise to use the "inhibit garbage collection"
or "don't use garbage collection" switch (-G in gbak), which will make
backup go A LOT FASTER. Garbage collection is used to clean up your
database, and as it is a maintenance task, it's often done together
with backup (as backup has to go throught entire database anyway).
However, you're soon going to ditch that database file, and there's no
need to clean it up.

Does performance of a database (SQL Server 2005) decrease if I shrink it?

Does performance of a database (SQL Server 2005) decrease if I shrink it?
What exactly happen to the mdf and ldf files when shrink is applied (Internals???)
When shrinking a database it will consume resources to shrink the DB. Where it runs into issues is when the DB needs to grow again, and assuming you have auto grow set, it will consume more resources to auto grow. Constant auto shrink (or shrink as part of maintenance plan) will cause physical disk fragmentation.
If you have auto grow enabled and it is set to the default of 1MB then constant auto grows will consume a lot of resources.
It is best practice to size your database to a size that is suitable, expected initial size plus expected growth over a period (month, year, whatever period you see fit). You should not use auto shrink or use shrink as part of a maintenance program.
You should also set your auto grow to MB (not a % of the database as when auto growing it needs to calculate the % first, then grow the database). You should also set the auto grow to a reasonable amount to ensure that it isnt going to be growing every 10 mins, try and aim for 1 or two growths a day.
You should also look at setting Instant Initialisation for your SQL Server.
Good luck,
Matt
It's important to understand that when you shrink a database, the pages are re-arranged. Pages on the end of the data file are moved to open space in the beginning of the file, with no regard to fragmentation.
A clustered index determines the physical order of data in a table. So, imagine that you just created a clustered index, which would have re-ordered the data in that table, physically. Well, then when you execute a shrink command, the data that had just been neatly ordered during the creation of the clustered index will now potentially be out of order, which will affect SQL's ability to make efficient use of it.
So, any time you do a shrink operation you have the potential of impacting performance for all subsequent queries. However, if you re-do your clustered indexes / primary keys after the shrink, you are helping to defragment much of the fragmentation that you may have introduced during the shrink operation. If performance is critical but you are also forced to do shrinks regularly, then in an ideal world you'd want to re-do your indexes after each shrink operation.
Yes it could affect performance a bit. When a database is in operation it doesn't care to much about its diskspace usage, more about efficient data retrieval/persistance.