SQL Server Performance Tuning For Developers

Chances are if you are reading this, you are a software developer.  Relax, I am one too, as well as a database administrator.  I spend a lot of time helping people to write code that is efficient or get the right results.  I want to share this post on SQL Database Tuning http://www.toptal.com/sql/sql-database-tuning-for-developers by Rodrigo Koch. It provides some really good advice, especially for beginners in the area.

Really hits the nail on the head though, keep it minimalistic. Only return what you need, it takes more time on the server and then the data has to go over the network.  He goes into some detail of how to troubleshoot slow queries and when to create indexes

 

Advertisement

Remotely connecting to SQL Server 2008 Integration Services – Access is denied error.

Very annoying error and I haven’t seen clear concise instructions for getting this to work. I will attempt to do that here.

  1. Open Administrative Tools > Component Services
  2. Navigate to DCOM Config and open the properties for MsDtsServer100
  3. Click on the Security tab
  4. Add the appropriate users/groups that you need and assign their permissions to BOTH “Launch and Activation Permissions” AND “Access Permisions” (Both of whom, select Customize then Edit)
  5. Click Ok to save changes and close those windows.
  6. Right click on Computer, select Manage.
  7. Navigate to System Tools > Local Users and Groups > Groups
  8. Double click on Distributed COM Users
  9. Add the users/groups you wanted to give permissions to.

SQL Server Database Corruption

I’m currently studying for the 70-450 exam to obtain my MCITP in SQL Server Database Administration. I wanted to get a better understanding for SQL Server’s transaction log. I wanted to see if I could corrupt a databases MDF and recover data even after the last t-log backup. This is where the tail backup comes in.

The tail log backup can recover your data even if the MDF is corrupted. This is because it stores all the transactions since the last full backup and t-log backup. If the MDF is corrupted your t-log should still be able  to be backed up, unless that is corrupted too. If the database is not truly corrupt, a backup log statement with the norecovery option will work just fine. This puts your database into recovery mode and prevents users from going into the database, preserving the state of the database so the restoration can be performed.

Unfortunately this does not work when the database is corrupted. You have to use the option continue_after_error, this forces the backup to occur.

You can then restore all data back to the database using your full and t-log backups.

Immediately after bringing the database online, be sure to make a full backup. This way you have a good restore point and if you routinely are backing up your t-logs, your next transactional backup will work just fine.

SQL Server – Searching for Non-Alphanumeric characters Using Like

All I can say is I have never really needed to search for a percent sign or square brackets or a caret in a query until today. GooBling (Googling and Binging) didn’t return any useful results. Of course Kim Tripp, one of the sage SQL Server gurus always recommends checking Books Online first, shame on me for not checking there first but this wasn’t entirely obvious. Check out the details here: http://msdn.microsoft.com/en-us/library/ms179859.aspx

You can specify an escape character using a very, now, obvious escape character. An escape character placed in front of a pattern matching character will force SQL Server to recognize the pattern matching character as a normal character.

For example:

SELECT * FROM table WHERE col1 LIKE ‘%|%%’ ESCAPE ‘|’

The above query will return all rows where col1 contains a percent sign.

SQL Server Rebuild or Reoganize Your Indexes – It depends, but here is a script I use.

So if you are like me, chances are you have that one server where the reindexing or reorganizing is taking a long time to finish. I came up with a solution that has helped me reduce the time it takes to maintain my indexes.

Background

Rebuilding indexes basically recreates an index from scratch (retrieving the data from the table again) whereas reorganizing is a process that relocates the pages of an index.

Rebuilding an Index

Rebuilding an index is typically an offline process, unless you have the Enterprise edition of SQL Server with the online flag set (check BOL for your particular version). While non-clustered indexes are being rebuilt, the table is available. However, rebuilding clustered indexes results in the the table being offline.

Reorganizing an Index

Reorganizing is an online process. It can reduce your fragmentation, but doesn’t always. Remember it is only moving pages around and not actually recreating the pages from data in the table.

Best Practices

Based on what I have read from various experts of SQL Server, rebuilding is recommended for indexes over 30 percent fragmentation. Under 30 percent, the index should be reorganized.

It is also recommended to not do anything to the indexes that are under 100 pages in size as they will not gain anything from a rebuild or reorganize. Of course, sometimes you might need to rebuild a small index, if for example, one of the pages has data corruption.

What the Script Does

Based on the best practices I mention above, it scans the sys.indexes view of every database on your SQL Server instance and then creates (and executes) rebuild or reogranize command for each index that has more than 5% fragmentation and more than 100 pages in size.

It uses the server default fill factor, which you can set in the properties of server instance.It currently DOES rebuild clustered indexes, so if you are running this be sure to run it in your maintenance window.

I encourage you to read through and understand the script as well as test it in your test environment before running it on production to get a feel for its behavior.

Let me know if it helps you out, I know it has helped me get more done in my maintenance window.

DECLARE @rebuildThreshold FLOAT;
SET @rebuildThreshold = 30.0;

CREATE TABLE #indices (
dbname VARCHAR(300),
tablename VARCHAR(300),
indexname VARCHAR(300),
fragmentation FLOAT
)
DECLARE @db SYSNAME;
DECLARE @sql VARCHAR(2000);

DECLARE curs CURSOR
FOR
SELECT  name
FROM    sys.databases
WHERE   name<>’tempdb’  AND state_desc <> ‘OFFLINE’ AND is_read_only = 0

OPEN curs

FETCH NEXT FROM curs INTO @db;
WHILE @@FETCH_STATUS=0
BEGIN
SET @sql = ‘SELECT ”’ + @db + ”’,
”[” + SCHEMA_NAME(schema_id) + ”].[” + OBJECT_NAME(i.object_id, DB_ID(”’ + @db + ”’)) + ”]”,
i.name AS indexname,
ips.avg_fragmentation_in_percent
FROM    sys.dm_db_index_physical_stats(DB_ID(”’ + @db + ”’), NULL, NULL, NULL, NULL) ips
INNER JOIN [‘ + @db + ‘].sys.indexes i ON ips.object_id=i.object_id AND
ips.index_id=i.index_id
INNER JOIN [‘ + @db + ‘].sys.objects o ON i.object_id = o.object_id
WHERE   page_count>=100 AND
avg_fragmentation_in_percent > 5’;

INSERT  INTO #indices
(
dbname,
tablename,
indexname,
fragmentation
)
EXEC (
@sql
);

FETCH NEXT FROM curs INTO @db;
END
CLOSE curs;
DEALLOCATE curs;

DECLARE curs2 CURSOR
FOR
SELECT  CASE WHEN fragmentation<@rebuildThreshold THEN ‘ALTER INDEX ‘ + indexname + ‘ ON [‘ + dbname + ‘].’ + tablename + ‘ REORGANIZE;’
ELSE ‘ALTER INDEX ‘ + indexname + ‘ ON [‘ + dbname + ‘].’ + tablename + ‘ REBUILD;’
END
FROM    #indices
WHERE   indexname IS NOT NULL;

OPEN curs2;

FETCH NEXT FROM curs2 INTO @sql;
WHILE @@FETCH_STATUS=0
BEGIN
EXEC (@sql);
PRINT @sql;

FETCH NEXT FROM curs2 INTO @sql;
END

CLOSE curs2;
DEALLOCATE curs2;

DROP TABLE #indices

Cannot fetch a row using a bookmark from OLE DB provider (Msg 7333, Level 16, State 2)

Linked Server Msg 7333

If you are getting this error and are trying to resolve it. Let me give you a little background information. A bookmark in this error is a left over from SQL Server 2005 SP1 and earlier. Bookmarks after 2005 SP1 is really a referred to as a key lookup, not to be confused with primary/foreign keys. From now on I am going to refer to bookmarks as key lookups so we are uniform and using the modern terminology.

Key lookups are objects within a query that refer to a data page (where the data is actually stored in the database) from a non-clustered index.

When SQL Server is executing DML (Insert, Update, Delete) against a linked server successfully for days, months, or even years and then fails with this error:

 Cannot fetch a row using a bookmark from OLE DB provider (Msg 7333, Level 16, State 2)

Something in the query execution plan is wrong. So far I have only run into this problem using linked servers and it probably has to do with resource management within SQL Server. Perhaps someone could elaborate on this that has more experience than I. But within the query’s execution plan, SQL Server decides to switch to a different index to run the query. The query then fails because it is using an index that is lacking information to complete the request.

Resolution

Ultimately, you have to do the following:

  1. Look at your where criteria in your query that is dependent on the linked server.
  2. Review indices on the table, that the where criteria is referring to.
  3. Is your one of your criteria covered by more than one index?

If you answered yes to number 3, there is a good chance that the behavior I am describing is actually causing your problem.

To diagnose this, disable one of the indexes  that is in question.

NOTE: Never disable the clustered index, you will prevent data access to the table.

Run the query again, and it should work, if not rebuild the disabled index to bring it back online and then disable the other index. If the query works you are in business. Talk with your database administrator, developer, or vendor of the application to come up with a good solution. But this will temporarily get your query to work.

SQL Server Reporting Services ~ MultiValued Parameters

This is a really good article on multivalued parameters in a stored procedure. Very good read for SQL Server Reporting Services.

Tech Updates

In SSRS reports we can have multi valued paremeters, which means we can select multiple values for that parameter and based on all those selected values result in the report is shown. We can write the SQL query to pass those parameter’s values and populate the data set, but sometimes it is required or to optimize the performance we need to use the stored procedure instead of direct sql query. This stored procedure will be taking the report paremeter as input and returing the result set to populate the data set.

In case of sql query as well as stored procedure, all selected values of the multi-value parameter will be passed as ‘,’ (comma) separated. So we should use IN clause in WHERE to impose the desired condition.

Problem: If we use stored procedure passing an input parameter which is multi-value parameter, SSRS will take all those selected multiple values…

View original post 398 more words

SQL Server Error 823 Troubleshooting and Resolution

SQL Server Error 823

If you are getting this error, chances are you are having a hardware failure on your server, or perhaps someone deleted one of the database files.

Assuming you took care of that situation:

Do not Detach the Database

The very easy fix to do is to simply restore the database using your backups. But if you don’t have a good set of backups, Paul Randal ( he and his wife Kim, are SQL GODS) has a great set of steps to try in his article here.

Here is the short story of how to get your database up and running if your transaction log was damaged.

Error 823 Resolution

Switch the database into the emergency/single-user mode:

alter database <dbname> set emergency;
go
alter database <dbname> set single_user;
go
dbcc checkdb(‘<dbname>’,REPAIR_ALLOW_DATA_LOSS) with all_errormsgs, no_infomsgs;
go
alter database <dbname> set multi_user;
go
alter database <dbname> set online;
go

The main thing to realize here is that if the transaction log is damaged or missing that the transactions are not going to be found in the transaction log. You are going to lose any active transactions that have not been commited to the database. The real area of interest is the REPAIR_ALLOW_DATA_LOSS. This particular arguement allows you to recreate the transaction log. Do not take this command lightly as it will lose data, so please use it only as a last resort.

 

DBA Test/Development Server Best Practices

These are things I learned from a hardware failure of a test server (you might also call it a staging area). So what’s the big deal? Developers should have all their code checked into source control and nothing critical should be on there right?

Sadly no. These are things you should do on your test server to limit your exposure as a DBA.

1. Treat the server as a production server. This includes transaction log backups, backups of user accounts, SSIS, SSRS, SQL Agent jobs, and Windows Tasks.

2. Trust, but verify. Trust the developers to be following best practices, after all your job is to make the company money and so is theirs. Periodically issue correspondence with the developers to verify that nothing is running in a production manner.

3. Get a good snapshot/system image from time to time. If someone or something destroys your server, you have something to fall back upon. This is especially true when developers are creating lots of dependencies in their code to OS level libraries.

Monitoring SQL Server with Profiler ~ 5 Things to Avoid

SQL Profiler

Everyone loves Profiler and for good reason, it provides you with good data to help you make your SQL Server run even better. To quote FDR, “great power involves great responsibility.” Here is a brief list of things to avoid.

Run Profiler on the same server as SQL Server.

This adds too much overhead to the server, please don’t do it, EVER! Ideally, run it on a test server that has some good system resources to be able to capture and analyse all that data.

Select too many events to trace.

For example, selecting Batch Begin and Batch Completed. Choose only what you need.

Don’t filter the results.

Filtering saves you time crawling through the results and saves SQL Server time. This falls back on number 3, choose only what you need.

Don’t join the Performance Monitoring data with Profiler data.

Why chase down a problem, that is not the real cause of your slow server? While you may see a small performance boost on the server, you may be missing the elephant in the room.