Sie sind auf Seite 1von 84

1

SQL Server DBA Responsibilities

Key Responsibilities DBA


We can categorize SQL Server DBA Responsibilities into 7 types

Capacity Management
Security Management

High Availability Management

Backup and Recovery Management

Performance Tuning

Process Improvements

Daily, Weekly and Monthly maintenance

Installations / Upgrades / Patching

Health Checks / Report Analysis

DBA Daily Responsibilities


On daily basis DBA should monitor the below
Backups

Confirm that backups have been made and successfully saved to a secure location
Check the backup failure alerts, correct the errors and rerun the backups

Review the average duration of backup, any significant changes occurred investigates on this. Most of
the time it happens due to networking low bandwidth

Validate the backup files using restore verify only. We can create jobs to take care of the task and to send
a notification if it fails to verify any backup.

Monitor all backup and log history is cleaning if it is designed.

Find out the newly added databases and define the backup plan

Disk Space

Verify the free space on each drive on all servers. If there is significant variance in free space from the
day before, research the cause of the free space fluctuation and resolve if necessary. Often times, log
files will grow because of monthly jobs.
Automate through a job. The job runs for every one hour and reports any drive which is having less than
15 % of free space. We can design a SSRS report to showcase and review the delta values.

Jobs / Maintenance plans

Check for the failed jobs, investigate the route cause and resolve the issue. Native SQL notification alert
sends a mail to DBA team and also we can design a customized SSRS report which reports all
failed/success job details with delta value.
Check for the job execution duration and if any significant changes find the root cause and resolve the
issue.

Make sure that all process related jobs/ maintenance plans completed. That includes data pulling jobs,
data update jobs etc.

All cleanup jobs are running fine, temp tables, logs, history, backup files etc

Servers/Databases

Confirm all servers/databases are up and running fine.


Usually in an Enterprise Database Environment Third Party Tools are used to monitor Servers (Ex:
Whats Up)

For database monitoring we can design a native SQL Server solution using T-SQL code and a
maintenance plan, it run min by min and send an email to DBA team if it is not able to connect to any of
the database in the instance.

Performance

Regularly monitor and identify blocking issues. We can design a procedure that continuously run on all
PROD servers and notifies DBA team if any blockings, long running quires/transactions.
Check Performance counters on all production servers and verify that all counters are within the normal
range. We can design a SSRS metrics report to review the counters for every one hour.

Throughout the day, periodically monitor performance using both System Monitor and DMV.

Check the fragmentation and rebuild/ reorganize the indexes. We can use a native procedure which takes
care of the task.

Make sure all Stats Update / nightly_checkalloc / Index_Rebuild jobs are completed without any issue.

Logs

Have a look at both SQL Server logs and Windows logs. If you find any strange issues notify the
network or storage teams. Most of the times we find Network related or I/O related issues.
Check the centralized error logs if any.

Security

Check the error logs for failed logins and notify the audit team if necessary
Security Logs Review the security logs from a third party solution or from the SQL Server Error Logs
to determine if you had a breach or a violation in one of your policies.

High-Availability

High Availability or Disaster Recovery Logs Check your high availability and/or disaster recovery
process logs. Depending on the solution (Log Shipping, Clustering, Replication, Database Mirroring,
CDP, etc.) that you are using dictates what needs to be checked.
We can design a native scripts using T-SQL to monitor Replication, Mirroring, Log shipping

Monitor logshipping and mirroring using the customized stored procs.

In most of the environments we see third party tools in monitoring Clusters or we can design our own
native scripts using Windows Batch Programming , Powershell and T-SQL.

Request Handling:

Check the escalated issues first


Check the current queue for requests and identify requests to be processed and work on the issue.

We usually process the requests based on the SLA.

Weekly / Monthly Checklist

Backup Verification (Comprehensive)- Verify your backups and test on a regular basis to ensure the
overall process works as expected. Contact your off site tape vendor and validate the type does not have
any restore errors
Check the logins, service accounts for expire dates

Backup Verification Verify your backups on a regular basis. Randomly choose one or two backups and
try to restore verify.

Windows, SQL Server or Application Updates Check for service packs/patches that need to be
installed on your SQL Server from either a hardware, OS, DBMS or application perspective

Capacity Planning Perform capacity planning to ensure you will have sufficient storage for a specific
period of time such as for 3, 6, 12 or 18 months.

Fragmentation Review the fragmentation for your databases to determine if you particular indexes
must be rebuilt based on analysis from a backup SQL Server.

Maintenance Schedule an official maintenance, do all required health checks on all premium databases
and servers.

Security Remove unneeded logins and users for individuals that have left the organization, had a
change in position, etc.

Moving data from production to archive: If your environment requires any specific DBA related data for
a long time, plan for an archival procedure. We can achieve data from actual OLTP system to other
dedicated DBA Server / Database

Monitoring Infrastructure

We need to work with the other teams to make sure that all servers are at health condition and to balance
the infrastructure.
Usually we approach other teams for below (CR/IR/SR Change Request/ Incident / Service)

Found I/O errors

Networking issues

F/R Flatten and Rebuild

Adding space / drives SAN (Storage Area Network)

Starting a Server When a manual interaction needed

Backup Tapes Archived backups

Escalating an issue

Documentation

Document all changes you make to the environment that includes:


Installations / Upgrades

Service packs / HotFixes applied

New databases added

Logins \ Roles added / removed

Check lists

Infrastructure changes

Process improvements

Maintain a centralized inventory with all details for below items

Database Servers

Application Servers

Web Servers

Logins (Both SQL Server and Windows)

Database Instances

Databases (Dev / Stag / QA / PROD)

Note: Document as much as information. It really helps in critical situations. Try to add owner at each level, for
example application owners, server owners etc. We can easily reach them in-case of any emergencies /
Maintenance.

Third Party Tools

MOM 2005 Microsoft Operational Manager for monitoring IT infrastructure


ApexSQL Monitor

SQL Spotlight by Quest

Microsoft Systems Center 2012 (SCOM)

SQL Monitor by RedGate

LiteSpeed

Netbackup

RoboCopy Copying data, files across servers

Heartbeat Database monitoring tool

WhatUp Server monitoring tool

Octopus Application deployment tool

Team Viewer Remote server connector

VNC Remote server connector

SQL DOC2 Reporting database architecture

Ignite Confio Monitoring Tool

Performance Tuning SQL Server Part 1

Q. What are the bottlenecks that effects the performance of a Database / Application
Ans:
The top performance bottlenecks for OLTP applications are outlined as:

Database Design \ Database Code


Application Design \ Application Code

CPU bottleneck

Memory bottleneck

IO bottleneck

Blocking bottleneck

Network bottleneck

Server Hardware

Database Design \ Database Code

Too many indexes on frequently updated (inclusive of inserts, updates and deletes):

Tables incur extra index maintenance overhead. Generally, OLTP database designs should keep the number of
indexes to a functional minimum, again due to the high volumes of similar transactions combined with the cost
of index maintenance

Statistics may not be updated or missing statistics


Excess use of cursors and temporary tables

Too much of normalization

Do not use the conversion/system/user defined functions in where clause

Unused indexes incur the cost of index maintenance for inserts, updates, and deletes without
benefiting any users:

Unused indexes should be eliminated. Any index that has been used (by select, update or delete operations) will
appear in sys.dm_db_index_usage_stats. Thus, any defined index not included in this DMV has not been used
since the last re-start of SQL Server

Choose the Appropriate Data Types

Always choose the smallest appropriate data type. Avoid NCHAR/NVARCHAR unless there is a need of
storing Unicode.

Use Triggers Cautiously

Keep the code in your triggers to the very minimum to reduce overhead. The more code that runs in the trigger,
the slower each INSERT, UPDATE, and DELETE that fires it will be

Dont Access More Data Than You Need

Dont return more columns or rows of data to the client than absolutely necessary. This just increases disk I/O
on the server

Avoid Using Cursors


Wherever possible Try to use alternative solutions includes Temp-Tables, Derived tables, Table Variables
or Recursive CTEs etc

Always select the cursor with the least amount of overhead. The most efficient cursor you can choose is
the fast forward-only cursor.

When you are done using a cursor, dont just CLOSE it, DEALLOCATE

Use Joins Appropriately

If you have two or more tables that are frequently joined together, then the columns used for the joins
should have an appropriate index. If the columns used for the joins are not naturally compact, then
considering adding surrogate keys to the tables that are compact in order to reduce the size of the keys,
thus decreasing read I/O during the join process, and increasing overall performance. You will learn
more about indexing in the next section of this article.

For best performance, the columns used in joins should be of the same data types. And if possible, they
should be numeric data types rather than character types.

Avoid joining tables based on columns with few unique values. If columns used for joining arent mostly
unique, then the SQL Server optimizer will perform a table scan for the join, even if an index exists on
the columns. For best performance, joins should be done on columns that have unique indexes.

If you have to regularly join four or more tables to get the recordset you need, consider denormalizing
the tables so that the number of joined tables is reduced. Often, by adding one or two columns from one
table to another, joins can be reduced.

Generally, frequent operations requiring 5 or more table joins should be avoided by redesigning the
database

Encapsulate Your Code in Stored Procedures

Try to put all your T-SQL code in stored procedures which reduces the network traffic by just calling the
proc from application and reduces the I/O overhead by using the compiled execution plan

Always use the option SET NOCOUNT ON

Design the procs to avoid the deadlocks

Collect all inputs before the transaction begins

Keep transaction short with in a batch

Use the correct isolation levels

Try to use with no lock option

Application Design / Application code:


Application Design issues:

Perform as many data-centered tasks as possible on SQL Server in the form of stored procedures. Avoid
manipulating data at the presentation and business services tiers.
Dont maintain state (dont store data from the database) in the business services tier. Maintain state in
the database as much as possible

Dont create complex or deep object hierarchies. The creation and use of complex classes or a large
number of objects used to model complex business rules can be resource intensive and reduce the
performance and scalability of your application. This is because the memory allocation when creating
and freeing these objects is costly.

Consider designing the application to take advantage of database connection pooling and object pooling
using Microsoft Transaction Server (MTS). MTS allows both database connections and objects to be
pooled, greatly increasing the overall performance and scalability of your application.

If your application runs queries against SQL Server that by nature are long, design the application to be
able to run queries asynchronously. This way, one query does not have to wait for the next before it can
run. One way to build in this functionality into your n-tier application is to use the Microsoft Message
Queue Server (MSMQ).

Application Code:

Use OLE DB to Access SQL Server:


o You can access SQL Server data using either ODBC or OLE DB. For best performance, always
select OLE DB. OLE DB is used natively by SQL Server, and is the most effective way to access
any SQL Server data.

Use DSN-less in Connection String:


o

Encapsulate your DML (Data Manipulation Language) in Stored Procedures


o

While creating an ADO connection to SQL Server, you can either use a DSN in the connection
string, or you can use a DSN-less connection. For optimal performance, use DSN-less
connections. Using them prevents the need for the OLE DB driver to look up connection string
information in the registry of the client the application code is running on, saving some
overhead.

ADO allows you three different ways to SELECT, INSERT, UPDATE, or DELETE data in a
SQL Server database. You can use ADOs methods, you can use dynamic SQL, or you can use
stored procedures. For better performance prefer Stored Procedures

Encapsulate Your ADO Code in COM Components


o

Put the ADO code that accesses SQL Server data into COM components. This gives you all the
standard benefits of COM components, such as object pooling using MTS. And for ASP-based
applications, it provides greater speed because the ADO code in COM objects is already
compiled, unlike ADO code found in ASP pages. How you implement your data manipulation
code in COM components should be considered when the application is first designed.

9
o

For optimum performance, COM objects should be compiled as in-process DLLs (which is
required if they are to run under MTS). You should always employ early binding when
referencing COM objects, and create them explicitly, not implicitly.

CPU bottlenecks:

Signal waits > 25% of total waits.

(See sys.dm_os_wait_stats for Signal waits and Total waits. Signal waits measure the time spent in the runnable
queue waiting for CPU. High signal waits indicate a CPU bottleneck.)

Plan re-use < 90%.

(A query plan is used to execute a query. Plan re-use is desirable for OLTP workloads because re-creating the
same plan (for similar or identical transactions) is a waste of CPU resources. Compare SQL Server SQL
Statistics: batch requests/sec to SQL compilations/sec. Compute plan re-use as follows: Plan re-use = (Batch
requests SQL compilations) / Batch requests. Special exception to the plan re-use rule: Zero cost plans will
not be cached (not re-used) in SQL 2005 SP2. Applications that use zero cost plans will have a lower plan reuse but this is not a performance issue.)
Memory bottleneck:

Consistently low average page life expectancy. (MSSQL$Instance: Buffer Manager\Page Life
Expectancy:)

(See Average Page Life Expectancy Counter which is in the Perfmon object SQL Server Buffer Manager (this
represents is the average number of seconds a page stays in cache). For OLTP, an average page life expectancy
of 300 is 5 minutes. Anything less could indicate memory pressure, missing indexes, or a cache flush)

Consistently low SQL Cache hit ratio. (MSSQL$Instance: Plan Cache\Cache Hit Ratio:)

(OLTP applications (e.g. small transactions) should have a high cache hit ratio. Since OLTP transactions are
small, there should not be (1) big drops in SQL Cache hit rates or (2) consistently low cache hit rates < 90%.
Drops or low cache hit may indicate memory pressure or missing indexes.)
IO bottleneck:

High average disk seconds per read.

(When the IO subsystem is queued, disk seconds per read increases. See Perfmon Logical or Physical disk (disk
seconds/read counter). Normally it takes 4-8ms to complete a read when there is no IO pressure. When the IO
subsystem is under pressure due to high IO requests, the average time to complete a read increases, showing the
effect of disk queues. Periodic higher values for disk seconds/read may be acceptable for many applications. For
high performance OLTP applications, sophisticated SAN subsystems provide greater IO scalability and
resiliency in handling spikes of IO activity. Sustained high values for disk seconds/read (>15ms) does indicate a
disk bottleneck.)

High average disk seconds per write.

10

(See Perfmon Logical or Physical disk. The throughput for high volume OLTP applications is dependent on fast
sequential transaction log writes. A transaction log write can be as fast as 1ms (or less) for high performance
SAN environments. For many applications, a periodic spike in average disk seconds per write is acceptable
considering the high cost of sophisticated SAN subsystems. However, sustained high values for average disk
seconds/write is a reliable indicator of a disk bottleneck.)

Big IOs such as table and range scans due to missing indexes.

Blocking bottleneck:

High average row lock or latch waits.

(The average row lock or latch waits are computed by dividing lock and latch wait milliseconds (ms) by lock
and latch waits. The average lock wait ms computed from sys.dm_db_index_operational_stats represents the
average time for each block.)

Top wait statistics


High number of deadlocks.

(See Profiler Graphical Deadlock under Locks event to identify the statements involved in the deadlock.)
Network bottleneck:

High network latency coupled with an application that incurs many round trips to the database.
Network bandwidth is used up.

(See counters packets/sec and current bandwidth counters in the network interface object of Performance
Monitor. For TCP/IP frames actual bandwidth is computed as packets/sec * 1500 * 8 /1000000 Mbps)
Server Hardware:
Most slow applications are slow because of poor up front design, not because of slow hardware. Since the
applications design cant be changed at the time when deployed to production, about the only thing you can try
to help boost performance is to throw hardware at it.

CPU: Always purchase a server with the ability to expand its number of CPUs. Usually it goes for larger
servers with four or more CPUs. Always leave room for growth.
Memory: Try to get enough RAM to hold the largest table you expect to have, and if you can afford it,
get all the RAM your server can handle, which is often 2GB or more.

I/O Subsystem: At the very minimum, purchase hardware-based RAID for your databases. As a rule of
thumb, you will to purchase more smaller drives, not fewer larger drives in your array. The more
disks that are in an array, the faster I/O will be.

Network Connection: At the server, have at least one 100Mbs network card, and it should be connected
to a switch. Ideally, you should have two network cards in the server connected to a switch in fullduplex mode.

11

For best performance on a server, SQL Server should be the only application running on the server, other than
management utilities. Dont try to save a few bucks by putting your IIS server on the same server as SQL
Server.
Q. What is the process of tuning the Performance?
Ans:

Identification Use native tools like Profiler, Query Tuning Advisor, Query Execution Plans,
Performance Monitor, system stored procedures, dynamic management views, custom stored procedures
or third party tools
Analysis Analyze the data to determine the core problems

Providing Solution

Creating new index on appropriate columns

Altering the complex quires to make them use the existing indexes.

By Updating Statistics for Tables and Views.

By Rebuilding and Reorganizing indexes.

By Resolving blocking problems.

By removing Deadlocks.

Testing Test the various options to ensure they perform better and do not cause worse performance in
other portions of the application

Knowledge sharing Share your experience with the team to ensure they understand the problem and
solution, so the issue does not occur again

Q. How to choose the correct (Clustered/ Non- Clustered) index on a column?


Ans: Selecting Clustered Index:

Clustered indexes are ideal for queries that select by a range of values or where you need sorted results.
Examples of this include when you are using BETWEEN, <, >, GROUP BY, ORDER BY, and
aggregates such as MAX, MIN, and COUNT in your queries.
Clustered indexes are good for queries that look up a record with a unique value (such as an employee
number) and when you need to retrieve most or all of the data in the record.

Clustered indexes are good for queries that access columns with a limited number of distinct values,
such as columns that holds country or state data. But if column data has little distinctiveness, such as
columns with a yes or no, or male or female, then these columns should not be indexed at all.

Avoid putting a clustered index on columns that increment, such as an identity, date, or similarly
incrementing columns, if your table is subject to a high level of INSERTS.

12

Selecting Non Clustered Index:

Non-clustered indexes are best for queries that return few rows (including just one row) and where the
index has good selectivity (above 95%).
If a column in a table is not at least 95% unique, then most likely the SQL Server Query Optimizer will
not use a non-clustered index based on that column. For example, a column with yes or no as the
data wont be at least 95% unique.

Keep the width of your indexes as narrow as possible, especially when creating composite (multicolumn) indexes. This reduces the size of the index and reduces the number of reads required to read the
index, boosting performance.

If possible, try to create indexes on columns that have integer values instead of characters. Integer values
have less overhead than character values.

If you know that your application will be performing the same query over and over on the same table,
consider creating a covering index on the table. A covering index includes all of the columns referenced
in the query.

An index is only useful to a query if the WHERE clause of the query matches the column(s) that are
leftmost in the index. So if you create a composite index, such as City, State, then a query such as
WHERE City = Houston' will use the index, but the query WHERE STATE = TX' will not use the
index.

Q. How to read the graphical execution plan?


Ans:
The plan should be read from right to left

Check the Graphical execution plan of a stored procedure / Query


Table Scan Index is missing

Index Scan Proper indexes are not using

BookMark Lookup Limit the number of columns in the select list

Filter Remove any functions from where clause, May require additional indexes

Sort Does the data really need to be sorted? Can an index be used to avoid sorting? Can sorting be
done at the client more efficiently?

DataFlow Arrow High density: Sometimes you find few rows as outcome but the arrow line density
indicates the query/proc processing huge number of rows

Cost Can easily find out which table / operation taking much time

From the execution plan we can find out the bottleneck and give the possible solution to avoid the
latency

Q. Why the Actual and Estimated Execution Plans Might Differ

13

Ans

When Statistics are Stale:

The main cause of a difference between the plans is differences between the statistics and the actual data. This
generally occurs over time as data is added and deleted.

When the Estimated plan is invalid:

When the batch contains temporary tables or the T-SQL statements which refers some of the objects that are not
currently existed in the database, but will be created once the batch is run. (Create table is there in batch)
Q. What are the permissions required to view execution plans?
Ans:
Either the user must be mapped to sysadmin, db_owner, db_creator or he/she will be granted the permission
Show Plan.
GRANT SHOWPLAN TO [username]
Q. What are the tools available for performance tuning/monitoring?
Ans:

Performance Studio: Act as a Central Data Repository, Collect Selected SQL Server Performance Data
and Display Performance Reports
Activity Monitor: It displays graphically about Processes, Resource Waits, Datafile I/O, Recent
expensive Quires.

Database Tuning Advisor (DTA): Recommend indexes

Profiler: Can run traces and find out the expensive/long running quires/transactions

Execution Plans: There are three types Graphical, Text and XML.

DMV: Dynamic management views shows the current state of the sql server

PerfMon: Windows native tool to view / monitor the performance of both sql and windows servers

Third Party: Redgate products

Q. How to identify the CPU bottlenecks and how to resolve it?


Ans:
Identifying CPU Bottlenecks:
Firstly we have to confirm that SQL Server CPU utilization is high. Run the below query
SELECT Timestamp, CONVERT(XML, record) AS XmlRecord

14

FROM SYS.DM_OS_RING_BUFFERS
WHERE ring_buffer_type = NRING_BUFFER_SCHEDULER_MONITOR
AND record like %<SystemHealth>%
ORDER BY timestamp DESC
One record is stored every minute up to a maximum of 256 records. Clicking on any of the XML links will take
you to the XML editor and will show an entry similar to below

<Record id=434 type=RING_BUFFER_SCHEDULER_MONITOR time=22398046>


<SchedulerMonitorEvent>
<SystemHealth>
<ProcessUtilization>55</ProcessUtilization>
<SystemIdle>35</SystemIdle>
<UserModeTime>228180000</UserModeTime>
<KernelModeTime>251812000</KernelModeTime>
<PageFaults>64252</PageFaults>
<WorkingSetDelta>21770240</WorkingSetDelta>
<MemoryUtilization>100</MemoryUtilization>
</SystemHealth>
</SchedulerMonitorEvent>
</Record>
Information from above XML:
ProcessUtilization: Percentage of CPU utilized by SQL Server 55%
SystemIdle: Percentage of Idle CPU 35%
Other processes using CPU: 100- (55+35) = 10 %
Now find out the query/proc/process that is making CPU utilization High:

15

SELECT TOP 20
qst.sql_handle,
qst.execution_count,
qst.total_worker_time AS Total_CPU,
total_CPU_inSeconds = Converted from microseconds
qst.total_worker_time/1000000,
average_CPU_inSeconds = Converted from microseconds
(qst.total_worker_time/1000000) / qst.execution_count,
qst.total_elapsed_time,
total_elapsed_time_inSeconds = Converting from microseconds
qst.total_elapsed_time/1000000,
st.text AS Query,
qp.query_plan
from
sys.dm_exec_query_stats as qst
CROSS APPLY sys.dm_exec_sql_text(qst.sql_handle) as st
cross apply sys.dm_exec_query_plan (qst.plan_handle) as qp
ORDER BY qst.total_worker_time DESC
From the above script we can find the commands which are taking the most CPU time along with the execution
plan. By reviewing the execution plan you can see what additional indexes need to be added to the database
which will improve database performance and decrease the CPU load time.
By adding missing indexes or by using the proper indexes we can decrease the load on CPU.
Other options:

Sp_monitor: Displays statistics, including CPU usage, I/O usage, and the amount of time idle since
sp_monitor was last executed. We can get the information about the CPU Time (Sec), I/O Time
(Sec), Count of Input\Output Packets, No of logins attempted, Errors in reading/writing network
packets etc.

16

@@CPU_BUSY / @@IO_BUSY: Returns the time that SQL Server has spent working since it was last
started. Result is in CPU time increments, or ticks, and is cumulative for all CPUs, so it may exceed
the actual elapsed time. Multiply by @@TIMETICKS to convert to microseconds. But it may not the
accurate value to be considered.

PerfMon

Profiler

Q. Can you tell me what the Wait Type LAZY WRITTER is?
Ans:
The job of the lazy writer is to find dirty pages in the buffer pool and write them out to disk and drop those
pages from cache.
Q. Can we find performance bottleneck from sysprocesses?
Ans:
Yes. We may not confirm that it is the only bottleneck but at least we can find the bottleneck. Lastwaittype
column with waittime plays a vital role in identifying the issue. This is a very interesting column because it can
tell you what the offending query is waiting for to complete.
Network_io: There is too much of traffic in Network
Cxpacket: Your process is waiting on other parallel processes to complete.
SOS_SCHEDULER_YIELD: CPU bound. We may not have enough CPU in your box
IO_Completion: Disk issue. We may not have enough disk space or running on corrupted disk array.
Q. What Are SQL Server Waits?
Ans:
Instead of measuring activity of CPU, storage, or memory, why not ask what SQL Server has been waiting on
when executing queries?
In general there are three categories of waits that could affect any given request:

Resource waits are caused by a particular resource, perhaps a specific lock that is unavailable when the
requested is submitted.
External waits occur when SQL Server worker thread is waiting on an external process
Queue waits normally apply to internal background tasks, such as ghost cleanup, which physically
removes records that have been previously deleted.

17

Q. How could you know the statistics are outdated?


Ans: If old statistics is your problem, you will likely experience this as a gradual decline of SQL Server
slowing down over many days or weeks, or you may have just upgraded your platform (from 2000 to 2008) and
forgot to update the statistics. Out of date statistics cause inaccurate execution plans.
Q. What are the main parameters we need to check when you are dealing with memory performance?
Ans: There are four significant properties of sql server.
Max server memory and Min server memory:
Use the two server memory options, min server memory and max server memory, to reconfigure the amount of
memory (in megabytes) that is managed by the SQL Server Memory Manager for a SQL Server process used by
an instance of SQL Server. By default Min Memory is set to be 0 and Max Memory is set to be 2147483647
MB (21 GB). Never leave these two settings as default. Depends on the memory available and other
applications running on windows Server, change these two settings.
For example we have 24 GB available and the settings can be like this:
Min Memory: 1 GB
Max Memory: 16 GB
Remember total max memory of all instances should not exceeds the actual physical memory available
Priority boost: By default, the priority boost setting is 0, which causes SQL Server to run at a normal priority.
If you set priority boost to 1, the SQL Server process runs at a high priority.
Lightweight pooling: Switch on this parameter when you want to make sql server use the fiber mode facility.
Unless there is a real need and environment (Large multi-processor servers) available we should not use this
option at production servers.

18

Performance Tuning SQL Server Part -2 Indexes


Q. What are the primary differences between an index reorganization and an index rebuild?
Ans:

Reorganization is an online operation by default; a rebuild is an offline operation by default


Reorganization only affects the leaf level of an index

Reorganization swaps data pages in-place by using only the pages already allocated to the index; a
rebuild uses new pages/allocations

Reorganization is always a fully-logged operation; a rebuild can be a minimally-logged operation

Reorganization can be stopped mid-process and all completed work is retained; a rebuild is transactional
and must be completed in entirety to keep changes

Q. During an index reorganization operation, if the index spans multiple files, will pages be allowed to
migrate between files
Ans: No pages will not migrate between files during an index reorganization.
Q. If you need to REBUILD a non-clustered index that is 10GB in size and have 5GB of free data-file
space available with no room to grow the data file(s), how can you accomplish the task?
Ans: When rebuilding an existing non-clustered index, you typically require free space that is approximately
equivalent to 2.2 times the size of the existing index, since during a rebuild operation, the existing index is kept
until the rebuilt structure is complete and an additional approximately 20% free space for temporary sorting
structures used during the rebuild operation

In this case, you would require at least an additional 10+ GB of free space for the rebuild operation to
succeed, since the index itself is 10GB in size.
Using SORT_IN_TEMPDB would not suffice in this case, since only the temporary sort tables are
stored in tempdb in this case, and at least 10 GB of free space would still be required in the database
data files.

Your possibilities are different for SQL Server2000 vs. SQL Server 2005/2008:

In SQL Server 2000, you only have 1 option in this case. Drop the index and recreate it.
In SQL Server 2005/2008, you can do the same as you did with SQL Server 2000 (drop, recreate), but
you also have another option. If you first disable the index (via the ALTER INDEXDISABLE
statement) the existing space consumed by the index will be freed. Then running a simple ALTER
INDEXREBUILD command will allow the build operation to use the now 15gb of free space to build
the index.

Q. What is the Covering Index?


Ans:If you know that your application will be performing the same query over and over on the same table,
consider creating a covering index on the table. A covering index, which is a form of a composite non clustered
index, includes all of the columns referenced in SELECT, JOIN, and WHERE clauses of a query. Because of

19

this, the index contains the data you are looking for and SQL Server doesnt have to look up the actual data in
the table, reducing logical and/or physical I/O, and boosting performance.
On the other hand, if the covering index gets too big (has too many columns), this could actually increase I/O
and degrade performance.
Q. What is Online Indexing?
Ans: Online Indexing is a new feature available in SQL Server 2005. In SQL Server 2005, DBAs can create,
rebuild, or drop indexes online. The index operations on the underlying table can be performed concurrently
with update or query operations. This was not possible in previous versions of SQL Server. In the past, indexing
operations (reorganizing or rebuilding) were usually performed as a part of other maintenance tasks running
during off-peak hours. During these offline operations, the indexing operations hold exclusive locks on the
underlying table and associated indexes. During online index operations, SQL Server 2005 eliminates the need
of exclusive locks
The Online indexing feature is very helpful for environments that run 24 hours a day, seven days a week. The
Online Indexing feature is available only in the Enterprise Edition of SQL Server 2005/2008.
Q. How Online Indexing works?
Ans: The online index operation can be divided into three phases:

Preparation
Build

Final

The Build phase is a longest phase of all. It is in this phase where the creation, dropping, or rebuilding of
indexes take place. The duration of the Build phase depends on the size of the data and the speed of the
hardware. Exclusive locks are not held in this phase, so concurrent DML operations can be performed during
this phase. The Preparation and Final phases are for shorter durations. They are independent of the size factor of
the data. During these two short phases, the table or the indexed data is not available for concurrent DML
operations.
Q. How to know unused indexes in a table.
Ans: By using a DMV well find the unused indexes details. We have a DMV called
sys.dm_db_index_usage_stats which retrieves the statistics of indexes , if an index id is not in that dmv then
we can say that index is not been using from a long time.
Q. What are the index limitations?
Ans:
INDEXTYPE 32 BIT / 64 BIT
NON CLUSTERED 999 / 999
XML indexes 249 / 249

20

Columns per index key 16 / 16 Only 900 Byte


Q. What are the different indexes available?
Ans: Index Types

Clustered Index: A clustered index sorts and stores the data rows of the table or view in order based on
the clustered index key. The clustered index is implemented as a B-tree index structure that supports fast
retrieval of the rows, based on their clustered index key values.
Non Clustered Index: A nonclustered index can be defined on a table or view with a clustered index or
on a heap. Each index row in the nonclustered index contains the nonclustered key value and a row
locator. This locator points to the data row in the clustered index or heap having the key value. The rows
in the index are stored in the order of the index key values, but the data rows are not guaranteed to be in
any particular order unless a clustered index is created on the table.
Unique Index: An index that ensures the uniqueness of each value in the indexed column. If the index is
a composite, the uniqueness is enforced across the columns as a whole, not on the individual columns.
For example, if you were to create an index on the FirstName and LastName columns in a table, the
names together must be unique, but the individual names can be duplicated. A unique index is
automatically created when you define a primary key or unique constraint:
o

Primary key: When you define a primary key constraint on one or more columns, SQL Server
automatically creates a unique, clustered index if a clustered index does not already exist on the
table or view. However, you can override the default behavior and define a unique, nonclustered
index on the primary key.

Unique: When you define a unique constraint, SQL Server automatically creates a unique,
nonclustered index. You can specify that a unique clustered index be created if a clustered index
does not already exist on the table.

Index with Included Columns: A nonclustered index that is extended to include nonkey columns in
addition to the key columns. They can be data types not allowed as index key columns. They are not
considered by the Database Engine when calculating the number of index key columns or index key
size. Need to use INCLUDE clause while creating index.

Full Text Indexes: A special type of token-based functional index that is built and maintained by the
Microsoft Full-Text Engine for SQL Server. It provides efficient support for sophisticated word searches
in character string data.

Spatial Indexes: A spatial index provides the ability to perform certain operations more efficiently on
spatial objects (spatial data) in a column of the geometry data type. The spatial index reduces the
number of objects on which relatively costly spatial operations need to be applied.

Filtered Index: An optimized nonclustered index, especially suited to cover queries that select from a
well-defined subset of data. It uses a filter predicate to index a portion of rows in the table. A welldesigned filtered index can improve query performance, reduce index maintenance costs, and reduce
index storage costs compared with full-table indexes. Use where clause in create index statement.

Composite index: An index that contains more than one column. In both SQL Server 2005 and 2008,
you can include up to 16 columns in an index, as long as the index doesnt exceed the 900-byte limit.
Both clustered and nonclustered indexes can be composite indexes.

21

XML Indexes: A shredded, and persisted, representation of the XML binary large objects (BLOBs) in
the xml data type column.

Q. I have a situation where I need to create an index on 20 columns. Is it practically possible? If yes
justify?
Ans: Yes ! We can create an index on 20 columns using INCLUDE clause.
You can include nonkey columns in a nonclustered index to avoid the current index size limitations of a
maximum of 16 key columns and a maximum index key size of 900 bytes. The SQL Server Database Engine
does not consider nonkey columns when calculating the number of index key columns or the total size of the
index key columns. In a nonclustered index with included columns, the total size of the index key columns is
restricted to 900 bytes. The total size of all nonkey columns is limited only by the size of the columns specified
in the INCLUDE clause; for example, varchar(max) columns are limited to 2 GB. The columns in the
INCLUDE clause can be of all data types, except text, ntext, and image.
Q. On which basis we will create computed indexes?
Ans:
For composite indexes, take into consideration the order of the columns in the index definition. Columns that
will be used in comparison expressions in the WHERE clause (such as WHERE FirstName = Charlie) should
be listed first. Subsequent columns should be listed based on the uniqueness of their values, with the most
unique listed first.
Q. How to design indexes for a database? Or
What are the index creation best practices?
Ans:

Understand the characteristics of the database (OLTP / OLAP)


Understand the characteristics of the most frequently used queries.

Understand the characteristics of the columns used in the queries.

Choose the right index at the right place. For example, creating a clustered index on an existing large
table would benefit from the ONLINE index option.

Determine the optimal storage location for the index. A nonclustered index can be stored in the same
filegroup as the underlying table, or on a different filegroup. If those filegroups are in different physical
drives it will improve the performance.

Database Considerations:

Avoid over indexing

Use many indexes to improve query performance on tables with low update requirements, but large
volumes of data.

22

Indexing small tables may not be optimal

Indexes on views can provide significant performance gains when the view contains aggregations and/or
table joins. The view does not have to be explicitly referenced in the query for the query optimizer to use
it

Column considerations:

Keep the length of the index key short for clustered indexes. Additionally, clustered indexes benefit from
being created on unique or nonnull columns.

Columns that are of the ntext, text, image, varchar(max), nvarchar(max), and varbinary(max) data types
cannot be specified as index key columns. However, varchar(max), nvarchar(max), varbinary(max), and
xml data types can participate in a nonclustered index as nonkey index columns

Columns that are of the ntext, text, image, varchar(max), nvarchar(max), and varbinary(max) data types
cannot be specified as index key columns. However, varchar(max), nvarchar(max), varbinary(max), and
xml data types can participate in a nonclustered index as nonkey index columns

Consider using filtered indexes on columns that have well-defined subsets

Consider the order of the columns if the index will contain multiple columns. The column that is used in
the WHERE clause in an equal to (=), greater than (>), less than (<), or BETWEEN search condition, or
participates in a join, should be placed first.

Index Characteristics: Determine the right index depends on the business need

Clustered versus nonclustered

Unique versus nonunique

Single column versus multicolumn

Ascending or descending order on the columns in the index

Full-table versus filtered for nonclustered indexes

Determine the Fill Factor

Q. Can we create index on table variables?


Yes, Implicitly
Create Index on Table Variable
Creating an index on a table variable can be done implicitly within the declaration of the table variable by
defining a primary key and creating unique constraints. The primary key will represent a clustered index, while
the unique constraint a non clustered index.
DECLARE @Users TABLE
(

23

UserID INT PRIMARY KEY,


UserName varchar(50),
UNIQUE (UserName)
)
The drawback is that the indexes (or constraints) need to be unique. One potential way to circumvent this
however, is to create a composite unique constraint:
DECLARE @Users TABLE
(
UserID INT PRIMARY KEY,
UserName varchar(50),
FirstName varchar(50),
UNIQUE (UserName,UserID)
)
You can also create the equivalent of a clustered index. To do so, just add the clustered reserved word.
DECLARE @Users TABLE
(
UserID INT PRIMARY KEY,
UserName varchar(50),
FirstName varchar(50),
UNIQUE CLUSTERED (UserName,UserID)
)
Q. What is the Heap Table?
Ans:
HEAP

Data is not stored in any particular order


Specific data cannot be retrieved quickly, unless there are also non-clustered indexes

24

Data pages are not linked, so sequential access needs to refer back to the index allocation map (IAM)
pages

Since there is no clustered index, additional time is not needed to maintain the index

Since there is no clustered index, there is not the need for additional space to store the clustered index
tree

These tables have a index_id value of 0 in the sys.indexes catalog view

Q. How to get the index usage information?


Q. Query to retrieve the indexes that are being used?
Ans:
sys.dm_db_index_usage_stats bind with sysobjects
This view gives you information about overall access methods to your indexes. There are several columns that
are returned from this DMV, but here are some helpful columns about index usage:

user_seeks number of index seeks


user_scans- number of index scans

user_lookups number of index lookups

user_updates number of insert, update or delete operations

sys.dm_db_index_operational_stats bind with sysindexes


This view gives you information about insert, update and delete operations that occur on a particular index. In
addition, this view also offers data about locking, latching and access methods. There are several columns that
are returned from this view, but these are some of the more interesting columns:

leaf_insert_count total count of leaf level inserts


leaf_delete_count total count of leaf level inserts

leaf_update_count total count of leaf level updates

SELECT DB_NAME(DATABASE_ID) AS DATABASENAME,


OBJECT_NAME(B.OBJECT_ID) AS TABLENAME,
INDEX_NAME = (SELECT NAME
FROM SYS.INDEXES A
WHERE A.OBJECT_ID = B.OBJECT_ID
AND A.INDEX_ID = B.INDEX_ID),
USER_SEEKS,
USER_SCANS,
USER_LOOKUPS,
USER_UPDATES
FROM SYS.DM_DB_INDEX_USAGE_STATS B
INNER JOIN SYS.OBJECTS C

25

ON B.OBJECT_ID = C.OBJECT_ID
WHERE DATABASE_ID = DB_ID(DB_NAME())
AND C.TYPE <> S
Q. What is fill factor? How to choose the fill factor while creating an index?
Ans:
The Fill Factor specifies the % of fullness of the leaf level pages of an index. When an index is created or
rebuilt the leaf level pages are written to the level where the pages are filled up to the fill factor value and the
remainder of the page is left blank for future usage. This is the case when a value other than 0 or 100 is
specified. For example, if a fill factor value of 70 is chosen, the index pages are all written with the pages being
70 % full, leaving 30 % of space for future usage.
Q. When to choose High or Low Fillfactor Value?
Ans:
You might choose a high fill factor value when there is very little or no change in the underlying tables data,
such as a decision support system where data modification is not frequent, but on a regular and scheduled basis.
Such a fill factor value would be better, since it creates an index smaller in size and hence queries can retrieve
the required data with less disk I/O operations since it has to read less pages.
On the other hand if you have an index that is constantly changing you would want to have a lower value to
keep some free space available for new index entries. Otherwise SQL Server would have to constantly do page
splits to fit the new values into the index pages.
Q. What methods are available for removing fragmentation of any kind on an index in SQL Server?
Ans:
SQL Server 2000:

DBCC INDEXDEFRAG

DBCC DBREINDEX

CREATE INDEXDROP EXISTING (cluster)

DROP INDEX; CREATE INDEX

SQL Server 2005 and above: The same processes as SQL Server 2000, only different syntax

ALTER INDEXREORGANIZE

ALTER INDEXREBUILD

CREATE INDEXDROP EXISTING (cluster)

26
o

DROP INDEX; CREATE INDEX

Q. What page verification options are available in SQL Server and how do they work?
Ans:
SQL Server 2000: Only Torn Page Detection is available in SQL Server 2000.
SQL Server 2005: Both Torn Page Detection and Checksum page verification options exist in SQL Server
2005. Page verification checks help to discover damaged database pages caused by disk I/O path errors. Disk
I/O path errors can be the cause of database corruption problems and are generally caused by power failures or
disk hardware failures that occur at the time the page is being written to disk.
TORN PAGE DETECTION:
Works by saving a specific bit for each 512-byte sector in the 8-kilobyte (KB) database page and is stored in the
database page header when the page is written to disk. When the page is read from disk, the torn bits stored in
the page header are compared to the actual page sector information. Unmatched values indicate that only part of
the page was written to disk. In this situation, error message 824 (indicating a torn page error) is reported to
both the SQL Server error log and the Windows event log. Torn pages are typically detected by database
recovery if it is truly an incomplete write of a page. However, other I/O path failures can cause a torn page at
any time.
CHECKSUM:
Works by calculating a checksum over the contents of the whole page and stores the value in the page header
when a page is written to disk. When the page is read from disk, the checksum is recomputed and compared to
the checksum value stored in the page header. If the values do not match, error message 824 (indicating a
checksum failure) is reported to both the SQL Server error log and the Windows event log. A checksum failure
indicates an I/O path problem. To determine the root cause requires investigation of the hardware, firmware
drivers, BIOS, filter drivers (such as virus software), and other I/O path components.
Q. What are the primary differences between an index reorganization and an index rebuild?
Ans:

Reorganization is an online operation by default; a rebuild is an offline operation by default


Reorganization only affects the leaf level of an index

Reorganization swaps data pages in-place by using only the pages already allocated to the index; a
rebuild uses new pages/allocations

Reorganization is always a fully-logged operation; a rebuild can be a minimally-logged operation

Reorganization can be stopped mid-process and all completed work is retained; a rebuild is transactional
and must be completed in entirety to keep changes

Q. During an index reorganization operation, if the index spans multiple files, will pages be allowed to
migrate between files

27

Ans:
No pages will not migrate between files during an index reorganization.
Q. How to make forcefully use an index in a query? Or What table hint needs to be specified to forcefully
use an index in a query?
Ans:
We can specify Index table hint in a query to forcefully use an index.
Ex: SELECT Emp_ID, Name FROM Emp WITH(INDEX(NIX_NAME_EMP))
Q. What are the index statistics?
Ans:
Index statistics contain information about the distribution of index key values. By distribution, I mean the
number of rows associated with each key value. SQL Server uses this information to determine what kind of
execution plan to use when processing a query.
Q. When are index statistics updated?
Ans:
The AUTO_UPDATE_STATISTICS database setting controls when statistics are automatically updated. Once
statistics have been created, SQL Server then determines when to update those statistics based on how out-ofdate the statistics might be. SQL Server identifies out of date statistics based on the number of inserts, updates,
and deletes that have occurred since the last time statistics were updated, and then recreates the statistics based
on a threshold. The threshold is relative to the number of records in the table. (Enable the properties auto
create statistics and auto update statistics for OLTP)
Q. Explain database options Auto Update Statistics and Auto Update Statistics Asynchronous?
Ans:
Auto Update Statistics: If there is an incoming query but statistics are stale then sql server first update the
statistics before building the execution plan.
Auto Update Statistics Asynchronous: If there is an incoming query but statistics are stale then sql servers
uses the stale statistics, builds the execution plan and then update the statistics.
Q. How to update statistics manually?
Ans:
If you want to manually update statistics, you can use either sp_updatestats or UPDATE STATISTICS
<statistics name>
Q. What are the various types of statistics available?

28

Ans:
There are three different types of statistics available.

Statistics created due to index creation.


Statistics created by optimizer.

User defined statistics created from CREATE STATISTICS

Q. What are the various options to be considered while designing a new execution plan?
Ans:
There are a number of factors that influence the decision in choosing the proper execution plan. One of the most
important ones are cardinality estimations, the process of calculating the number of qualifying rows that are
likely after filtering operations are applied. A query execution plan selected with inaccurate cardinality
estimates can perform several orders of magnitude slower than one selected with accurate estimates. These
cardinality estimations also influence plan design options, such as join-order and parallelism. Even memory
allocation, the amount of memory that a query requests, is guided by cardinality estimations.
Other factors that influence the optimizer in choosing the execution plan are:

Q. How histogram built?


Ans:
As we all know that when we index a column, SQL Server does two things:
1. Sorts the values of the column in an internal data structure called Index This data structure contains
the sorted value and a pointer to its respective row in the table.
2. Generates a histogram of values.
The histogram shows the distribution of values for the sorted column. For example:

29

if we have following values in an integer column 1,2,2,3,4,1,4,5,4 then a typical histogram will be similar to this
Value
1
2
3
4
5

Rows matched
2
2
1
3
1

So suppose if you are searching for all rows having column values between 3 and 5 then by looking at the
above histogram table you can estimate that you will get total 1+3+1=5 rows. If your table contains just 9
rows in total then 5 rows means approximately 55% of total rows will match the criteria. Based on this
calculation you may elect to directly scan the table instead of first reading the index, fetching the pointers of the
matching rows and then read the actual rows. Although, it is a very simple example and there are other factors
involve in deciding whether to use index or not but this example demonstrates the concept in very simple terms.
Q. How to find out when statistics updated last time?
Ans:
A simple logic is, run the query and observe the values for both estimated rows and actual rows, if they
both are close to each other you need not worried about the statistics. If you find big difference between them
then you need to think about updating statistics.
In general we can find out last statistics updated info from below query
select object_name(object_id) as table_name
,name as stats_name
,stats_date(object_id, stats_id) as last_update
from sys.stats
where objectproperty(object_id, IsUserTable) = 1
order by last_update
Q. What is RID Lookup \ Bookmark Lookup?
Ans:
RID lookup will be seen when you use non-clustered indexes with join queries.
In order to understand the RID look up we need to first understand how non-clustered indexes work with
clustered indexes and heap tables. Below is a simple figure which describes the working and their relationships.

30

Non-clustered indexes also use the B-tree structure fundamental to search data. In non-clustered indexes the leaf
node is a Rowid which points to different things depending on two scenarios:Scenario 1:- If the table which is having the primary key in the join has a clustered index on the join key then
the leaf nodes i.e. rowid will point to the index key of clustered index hence a clustered index seek happens
Scenario 2 :- if the table which is having the primary does not have a clustered index then the non-clustered
index leaf node rowid will point to actual row on the heap table. As the data is stored in a different heap table,
it uses the lookup (i.e. RID lookup) to get to the actual row hence an Index seek (Non clustered) with RID
lookup happens

Performance Tuning SQL Server Part 3 TempDB


Q. Tempdb is filling up drastically, what might be the activity that filling up the tempdb?

31

Ans:
Usually, tempdb fills up when you are low on disk space, or when you have set an unreasonably low maximum
size for database growth.
Many people think that tempdb is only used for #temp tables. When in fact, you can easily fill up tempdb
without ever creating a single temp table. Some other scenarios that can cause tempdb to fill up:

Any sorting that requires more memory than has been allocated to SQL Server will be forced to do its
work in tempdb
DBCC CheckDB(any database) will perform its work in tempdb on larger databases, this can
consume quite a bit of space

DBCC DBREINDEX or similar DBCC commands with Sort in tempdb option set will also potentially
fill up tempdb

Large resultsets involving unions, order by / group by, cartesian joins, outer joins, cursors, temp tables,
table variables, and hashing can often require help from tempdb

Any transactions left uncommitted and not rolled back can leave objects orphaned in tempdb

Use of an ODBC DSN with the option create temporary stored procedures set can leave objects there
for the life of the connection

Table value functions that pull large data sets hold their data in tempdb

If you are using Snapshot isolation on a database with a high number of transactions the snapshot data is
stored in tempdb

Q. How to analyze the TempDB contention


Ans:

Run the below command

USE tempdb
GO
SELECT table_name FROM information_schema.tables
If you have a few tables, then you are most likely dealing with a large set issue. If you have a very large number
of tables, then there is a runaway process or an unclosed process.

Find the size of the tables. Shortlist the biggest tables and depends on the type of table we can find out
the source.
Make sure that disk space is not full and capacity settings for tempdb (low size for max growth)

Also with queries that fail to use an index on large tables can cause this from time to time. Do you have
autoshrink turned on for tempdb

32

You could check in on your record locking strategies for your executable sessions and/or records might
not be getting released properly. Use the query optimizer tools maybe
Check for index rebuilding jobs, data pulling jobs/triggers blocking sessions, long running transactions

Use profiler / perfmon / dbcc commands to find the bottlenecks

You can use Profiler to watch for events like database file auto grow and log file auto grow. If this is
happening often, then you know that the space youve allocated to tempdb is not sufficient.

You can also watch performance monitors counter for PhysicalDisk: CurrentDiskQueueLength on the
drive where tempdb exists. If this number is consistently greater than 2, then there is likely a bottleneck
in disk I/O.

Q. How to fix the TempDB filling issue?


Ans:
Short-Term Fix:

Shrink Tempdb: We can shrink the db using ShrinkDatabase, DBCC ShrinkFile. If you cant shrink the
log, it might be due to an uncommitted transaction.
See if you have any long-running transactions with the following command dbcc opentran(tempdb)

Check the oldest transaction (if it returns any), and see who the SPID is DBCC
INPUTBUFFER(SPID)

Query will help you determine if you want to end this process with KILL SPID

Restarting SQL Server will re-create tempdb from scratch, and it will return to its usually allocated size.
In and of itself, this solution is only effective in the very short term; assumedly, the application and/or TSQL code which caused tempdb to grow once will likely cause it to grow again.

Long-Term Prevention:

Make sure that tempdb is set to autogrow do *NOT* set a maximum size for tempdb. If the current
drive is too full to allow autogrow events, then buy a bigger drive, or add files to tempdb on another
device (using ALTER DATABASE) and allow those files to autogrow.
For optimal performance, make sure that its initial size is adequate to handle a typical workload
(autogrow events can cause performance to suffer as it allocates new extents).

If possible, put tempdb on its own physical disk, array or disk subsystem

To prevent tempdb log file growth, make sure tempdb is in simple recovery mode

Try to make sure you have covering indexes for all large tables that are used in queries that cant use a
clustered index / index seek.

In general, try to make your code as efficient as possible avoid cursors, nested loops, and #temp tables
if possible.

Make sure all the transactions are having the corresponding Commit and Rollback

33

Q. The most common argument I heard is table variables are in-memory structures (stored in memory
not on tempdb) not like temporary tables. Is that true? How can you justify?
Ans:
Its actually a wrong assumption; both table variables and temp tables are stored in tempdb. A DMV
sys.dm_db_session_space_usage can help us to make sure these objects use Temdb.
On a development machine restart the SQL server and select data from above DMV as below.
SELECT session_id,
database_id,
user_objects_alloc_page_count
FROM sys.dm_db_session_space_usage
WHERE session_id > 50 ;

Initially user_objects_alloc_page_count is shown as 0.


Create a simple temporary table and insert test data and now check the same DMV, we can see the page_count
as 1.
Then create a table variable and insert a row and we can see the page_count increased to 2.
Q. What database objects are stored in tempdb?
Ans:
There are three different types of objects stored in tempdb.
Internal Objects:
1. Intermediate runs for sort.
2. Intermediate results for hash join and hash aggregates.
3. XML variables or other large object (LOB) data type variables. (text, image, ntext, varchar(max),
varbinary(max))
4. Queries that need a spool to store intermediate results.
5. Keyset cursors to store the keys.
6. Static cursors to store a query result.
7. Service Broker to store messages in transit.

34

8. INSTEAD OF triggers to store data for internal processing.


9. DBCC CHECK internally uses a query that may need to spool intermediate results.
10. Query notification and event notification use Service Broker.
Note:
Page allocations on internal objects and Updates to internal objects do not generate log records.
Does not appear in catalog views such as sys.all_objects
Version Store:
1. Snapshot Isolation / Read Committed Snapshot Islotaion
2. Triggers (After Triggers). Instead of triggers doesnt generate versions.
3. MARS (Multiple Active Result Sets)
4. Index Rebuilds
Note:
Inserts into version stores do not generate log records.
Does not appear in catalog views such as sys.all_objects
User Objects:
1. User defined tables and indexes
2. Local and global temporary tables, bulk insert and BCP intermediate results
3. Index rebuilds with SORT IN TEMPDB option.
Note:
Most of the operations under this category are bulk logged.
Appear in catalog views such as sys.all_objects.

35

Low Level SQL Server Architecture


SQL Server Architecture
Here we would like to describe the process architecture whan a new request submitted to SQL Server.
we have submitted a Query to SQL Server from an Application and we got the reply as data inserted
successfully. What are the overall processes worked inside?
At Client:
1. User enter data and click on submit
2. The client database library transforms the original request into a sequence of one or more Transact-SQL
statements to be sent to SQL Server. These statements are encapsulated in one or more Tabular Data Stream
(TDS) packets and passed to the database network library
3. The database network library uses the network library available in the client computer to repackage the TDS
packets as network protocol packets.
4. The network protocol packets are sent to the server computer network library across the network
At Server:
5. The extracted TDS packets are sent to Open Data Services (ODS), where the original query is extracted.
6. ODS sends the query to the relational engine
7. A connection established to the relational engine and assigns a SID to the connection

At Relational Engine:
8. Check permissions and determines if the query can be executed by the user associated with
9. Query sends to Query Parser
It checks that the T-SQL is written correctly
Build a Parse Tree \ Sequence Tree
10. Parse Tree sends to Algebrizer
Verifies all the columns, objects and data types

the request

36

Aggregate Binding (determines the location of aggregates such as GROUP BY, and MAX)

Builds aQuery Processor Tree in Binary Format

11. Query Processor Tree sends to Optimizer


Based on the query processor tree and Histogram (Statistics) builds an optimized execution plan
Stores the execution plan into cache and send it to the database engine

At Database Engine:
12. Database engine map a batch into different tasks
13. Each task associated with a process
14. Each process assigned with a Windows Thread or a Windows Fiber. The worker thread takes care of this.
15. The Thread/Fiber send to the execution queue and wait for the CPU time.
16. The Thread/Fiber identifies the table location where the data need to be stored
17. Go to the file header, checks the PFS, GAM and GSAM and go to the correct page
18. Verifies the page is not corrupted using Torn page Detection / Check SUM and writes the data
19. If require allocates new pages and stores data on it. Once the data is stored/updated/added in a page, it
updates the below locations
PFS Page Free Space
Page Header Checksum / Torn Page Detection (Sector info)

BCM Bulk Change MAP

DCM Differential Change MAP

20. In this process the


Memory manager take care of allocating buffers, new pages etc,
Lock manager take care of allocating appropriate locks on the objects/pages and releasing them when
task completed

Thread Scheduler: schedules the threads for CPU time

I/O manager: Establish memory bus for read/write operations from memory to disk and vice versa

Deadlock\Resource\Scheduler Monitor: Monitors the processes

21. Once the process is completed the result set is submitted to the relational engine and follow the same
process for sending back the result set to client application.
22. The connection will be closed and the SID is removed.

37

This information I have collected from various articles and reading through books online.

Guide to Indexes
In this article, we take a brief look at the different kinds of indexes that exist in SQL Server, and how they work.
To get us started on this journey, we first need to answer these two questions:

What is a table?
What is an index?

Once we are clear on these terms, we will then explore each of the following variations of indexes available in
SQL Server 2005 and SQL Server 2008:

Clustered
Non-clustered

Indexed view

Computed

XML

Filtered (New with SQL Server 2008)

Spatial (New with SQL Server 2008)

Compressed Indexes (New to SQL Server 2008)

If you are already intimately familiar with all of the above, then there is no need for you to read this article. If,
on the other hand, you need to start with a simple introduction to indexes for the beginner, please read Rob
Sheldon's excellent SQL Server Index Basics first.
Note: The explanations in this article have been simplified to make the concepts easier to understand. In the real
world, things are more complex. For complete coverage of SQL Server index internals, read the book Microsoft
SQL Server 2008 Internals by Kalen Delaney et al.

What is a Table?
Tables can be thought of in either logical or physical terms. For example, when most DBAs think of a table,
they see a two-dimensional set of values arranged into rows and columns, similar in appearance to a
spreadsheet. Each column represents a different data element, and each row represents a collection of related
data elements.
For example, in figure 2-1 below, we see a representation of a logical table that has three columns and four
rows. This should look very familiar to DBAs as this is how most of us visualize what a table in a database
looks like. It also looks similar to the results we see when we perform a SELECT statement on a table within
Management Studio.

38

Figure 2-1: A logical table with three data columns and four rows.
While a logical visualization of table is very handy for DBAs to use in their work, this is not how SQL Server
sees a table. When a table is created, it has to be implemented physically inside a database.
For example, the most basic structure is the database file (.mdf and .ndf files). The database file can include
many objects, but for now, we want to focus on tables. As seen in figure 2.2 below, a database file will include
one or more tables.
(Note: I am ignoring transaction the log file (.ldf) because it is not part of a tables physical structure.)

Figure 2-2: A database file is the physical container that holds tables.
Each table in a database can be broken into multiple components. Lets take a brief look at each of them so we
better understand what makes up a physical table within SQL Server.

39

Figure 2-3: A table has many components.


At the top of figure 2-3, we start with the table, and then we see it split into many components. The first
component is a partition. A partition is simply a way DBAs can sub-divide rows in a table (and the tables
indexes) into separate sections, generally for the purpose of horizontally spreading rows across more than one
filegroup. This often makes it easier for DBAs to manage and scale very large tables. The topic of partitioning is
outside the scope of this article, so all the following examples will assume there is a single partition (which is
the default option when creating a table). In addition, only the Enterprise and Developer editions of SQL Server
support partitioning.
Partitions contain data rows stored in either the physical form of a heap (a table without a clustered index) or a
B-Tree structure (a table with a clustered index). We will go into a more detailed explanation of these structures
in the next section.
Heap and B-Tree structures contain one or more allocation units. This is just a fancy way of subdividing
different data types into three categories, which are:

In_Row_Data: This is the most common type of allocation unit, and is used to store data
and index pages, except for Large Object (LOB) data. In other words, most of your row
data (and related indexes) are stored in this type of allocation unit.
Lob_Data: Used to store Large Object (LOB) data, such as text, ntext, xml, image,
varchar(max), nvarchar(max), varbinary(max), and CLR user-defined data types.

40

Row_Overflow_Data: Used to store data pages when the variable data typesvarchar,
nvarchar, varbinary, and sql_variant data columnsthat exceed the 8,060 bytes that can
fit onto a single data page.

If a heap or Be-Tree structure does not have a need for all three allocations units, then they may or may not have
them. Besides the data described above, each of these allocation units also include various metadata to help
manage the data within each allocation unit.
Allocation units themselves are made up of extents. In figure 2-3, we see that each allocation unit has one
extent. In the real world, each allocation unit would include many, many extents.
An extent is a collection of eight contiguous 8K pages (for a total of 64K). A page is the most elemental unit of
data storage used by SQL Server, and will be the focus of our next discussion.
Note: Why are extents used to group eight 8K pages? Extents are used because it is more resource efficient for
SQL Server to allocate eight, 8K pages in a single step than it is for SQL Server to create eight, 8K pages in
eight separate steps. There are two types of extents: uniform and mixed extents. All eight pages of a uniform
extent are all owned by the same object. In a mixed extent, each page of the extent can be owned by a different
object. Why are there two different kinds of extents? This is because many objects in a database are less than
64K in size. If only uniform extends were allowed, then there would be a lot of wasted space on extents that are
not fully used by an object. By allowing mixed extends, multiple, smaller objects can all fit onto a single extent,
which makes more efficient use of available space. Whenever a new table or index is created, it generally is first
created on a mixed extent. What happens if an object on a mixed event grows to exceed 64K? If that happens,
all future page allocations are done using uniform extents.
While the basic unit of data storage in SQL Server is the page, there are eight different types of pages available
for SQL Servers use. They include:

Data: Stores most data types, except for text, ntext, image, nvarchar(max), varchar(max),
varbinary(max), and xml data (when the text in row option is set to on).
Index: Stores indexes (root and intermediate level pages of a B-Tree structure).

Text/Image: Stores LOB data types, such as text, ntext, nvarchar(max), varchar)max),
xml data, and if variable length columns exceed 8K, then varchar, nvarchar, varbinary, and
sql_variant data.

Global Allocation Map (GAM)/Shared Global Allocation Map (SGAM): Stores


tracking information about extents that have been allocated.

Page Free Space (PFS): Stores information about allocated pages, and the amount of
free space available on them.

Index Allocation Map (IAM): Stores data about extents that are used by a table or
index, per allocation unit.

Bulk Changed Map: Stores data about any extents that have been changed by a bulk
operation since the last transaction log backup, per allocation unit.

Differential Changed Map: Stores data about any extents that have been changed since
the last database backup, per allocation unit.

41

For the purpose of this article we will focus mostly on data, index, and Text/Image data pages, which are the
most relevant to us in our goal of high performance index maintenance. When we talk about heaps later in this
article, we will briefly discuss IAM pages.
Because pages are so important to us, lets take a quick look at what a data page looks like.

Figure 2-4: This is an idealistic depiction of a data page.


Every SQL Server page (8,192 bytes) begins with a 96-byte header used to store metadata about the page. This
includes the pages number, page type, amount of free space on the page, the allocation unit ID of the object that
owns the page, among other metadata.
Note: We need to learn how data pages work, as this directly affects our understanding of index fragmentation
Immediately following the page header is the data to be stored, one row after another. Each page can store a
maximum of 8,060 bytes. The number of rows that can be stored on a page depends on the size of the rows. For
example, the smaller the rows, the more rows that can fit on a single data page. When a page becomes full, any
new data will be inserted in another data page.
Figure 2-4 is not a realistic depiction of how rows are stored on a data page. In the figure, it appears as if each
row uses the identical amount of space to store its data. In the real world, each row may be a different length,
which means that the beginning and ending of each row can be anywhere within the page.

42

If rows are packed in, one after another, and if each row can vary in size, how does SQL Server know when a
row starts and when it ends? That is what row offsets are used for. Every row in a page has a row offset, which
indicates how far the first byte of the row is from the start of the page. Row offset data is stored at the bottom of
a page in an area reserved for this information.
For example, when the first row is added to a page, the location of the first byte of that row is stored in offset
row one. When row two is added, the location of the first byte of the second row is stored in offset row two,
and so on. This way, SQL Server knows where each row begins and ends.
Now that you have a basic understanding of how SQL Server stored data, its time to talk about the heaps and
B-Trees structures that we talked about briefly a little earlier.

What is a Heap?
A heap is simply a table without a clustered index. (We will talk about clustered indexes later in this article).
When rows are added to a heap, they are not stored in any particular order on a data page, and data pages are
not stored in any particular sequence within a database. In other words, rows are stored wherever there is room
available. This means that the data pages that contain the rows of the heap may be scattered throughout a
database, in no particular order.
Note: A heap can have non-clustered indexes, but it does not have a clustered index.
Since a table cant exist as a bunch of scattered pages, SQL Server provides a way to link them all together so
that they act as a single table. This is done using what are called Index Allocation Map (IAM) pages. IAM pages
manage the space allocated to heaps (among other tasks), and is what is used to connect the scattered pages (and
their rows) into a table.

43

Figure 2-5: Data pages in a heap are tracked by IAM pages. Because of this, each row in a heap must first be
looked up in an IAM page so that is can be located.
For example, lets say that a query is executed against a heap, and a table scan has to be performed to find the
data to be returned. In order to find the rows in the table that need to be scanned, the SQL Server Database
Engine first goes to an IAM page, which includes pointers to the various extents and pages that contain the rows
of the table that belong to the heap. If a heap is large, numerous IAM pages and data pages have to be
examined before all the rows are located and scanned. If the data pages happen (by coincidence) to be
physically contiguous, then such scans can be I/O efficient because sequential reads can be used to read the
data. But in many cases, the various heap pages are scattered about, which requires less efficient random reads
to scan through all the rows of the table, which can hurt performance.
While tables, taking the form of heaps, can easily be created in SQL Server, using them has many
disadvantages. Some of them include:

If non-clustered indexes are not added to a heap, then all queries against a heap will
require table scans to retrieve the requested data. If the heap is large, then these queries
will be very resource intensive and hurt SQL Servers overall performance.
Since the data in a heap is unordered, performing a table scan on a heap can cause a lot
of extra I/O activity because inefficient random reads, not efficient sequential reads, are
more the norm.

44

While a non-clustered index can be added to a heap to speed up some queries, when the
non-clustered index is non-covering, the use of a RID bookmark lookup is required. A RID
lookup means that once the record(s) to be returned by the query are identified in the nonclustered index, additional reads (the RID bookmark lookup) must be made of the related
rows in the heap, so that all of the data requested by the query is returned. This is not
very I/O efficient, especially if many rows are returned. At some point, it may be faster for
SQL Server to do a table scan than it is to use a non-clustered index when returning many
rows. On the other hand, if the non-clustered index is covering, then the non-clustered can
be used to immediately return the data to the user without having to lookup anything in
the heap.

If you want to create an XML index on an XML data column, a clustered index must exist
on the table.

If you want to create a spatial index on a spatial data column (GEOMETRY or GEOGRAPHY),
a clustered index must exist on that table.

If a heap has a non-clustered index on it (as the primary key), and data is inserted into the
table, two writes have to occur. One write for inserting the row, and one write for updating
the non-clustered index. On the other hand, if a table has a clustered index as the primary
key, inserts take only one write, not two writes. This is because a clustered index, and its
data, are one in the same. Because of this, it is faster to insert rows into a table with a
clustered index as the primary key than it is to insert the same data into a heap that has a
non-clustered index as its primary key. This is true whether or not the primary key is
monotonically increasing or not.

When data is updated in a heap, and the updated row is larger than the old row and cant
fit into the old space, a forwarding record is inserted into the original location that points
to the new location of the page. If this happens a lot, then there is a lot of space wasted in
a database maintaining the forwarding records. This also contributes to additional I/O
activity as both the pointer, and the row, have to be read.

Even if data updated in a heap is not larger than the old row (the updated data is smaller
or the same size than the original data), updating a heap with a non-clustered primary key
is slower than updating the same table that has a clustered index as the primary key. This
is because updating a table with a clustered index is less write intensive than updating a
heap with a non-clustered index as its primary key.

If a row is deleted from a heap with a non-clustered index as its primary key, it is slower
than deleting the same row from the same table with a clustered index as its primary key.
This is because it takes more I/O to perform this task on a heap than on a clustered index.

When data is deleted from a heap, the data on the page is not compressed (reclaimed).
And should all of the rows of a heap page are deleted, often the entire page cannot be
reclaimed. This not only wastes space, it contributes to fragmentation of the data pages
within a database.

If you take two identical tables, one that is a heap with a non-clustered index as its
primary key, and a table that has a clustered index as its primary key, the heap with the
non-clustered index will be substantially larger, wasting valuable space and increasing disk
I/O.

The ALTER INDEX rebuild and reorganize options cannot be used to defragment and
reclaim space in a heap (but they can used to defragment non-clustered indexes on a
heap). If you want to defragment a heap in SQL Server 2005, you have three options: 1)

45
create a clustered index on the heap, then drop the clustered index; 2) Use SELECT INTO
to copy the old table to a new table; or 3) use BCP or SSIS to move the data from the old
table to a new table. In SQL Server 2008, the ALTER TABLE command has been changed so
that it now has the ability to rebuild heap.

Given all of these negatives, it is highly recommended that all tables have a clustered index. In fact, for the
purpose of this article, we will make the assumption that all the tables we are working with have clustered
indexes (and are not heaps).

What is an Index?
In the previous section we talked about heaps, which are tables without a clustered index. In this section, we
will talk about what an index is. Later, we will talk about specific kinds of indexes that can be added to SQL
Server tables.
As I have already mentioned, an index is simply a way to help queries return data faster from tables. In SQL
Server, all indexes physically take the form of what is called a B-Tree.
Note: The B in B-Tree refers to balanced, so B-Tree is short for Balanced Tree. This is because a B-Tree
index self balances, which means that every time a tree branches (splits into two pages because the original
page is full), about half of the data is left on the old page, and the other half is put on the new page. One of the
key benefits of having a Balanced Tree is that finding any particular row in a table requires about the same
amount of SQL Server resources because the index has the same depth (number of levels) throughout its
structure.

Figure 2-6: All indexes in SQL Server use the B-Tree index structure.
Lets say that we want to perform a query on a table to find rows that have a Customer Number of 4. One
option would be to scan through all the rows in the table until we find one or more rows that have a customer
number of 4. (Note: For this example, we are making the assumption that the rows in this table may not be
unique.) If the table is small, then a scan of all the rows in the table will be fairly quick. But if the table is very
large, say over 1 million rows, then scanning every row would be time consuming. Instead, another option is to
use an index to find the rows that match the query criteria much more quickly than scanning each and every row
found in the table.

46

In figure 2-6 is a simplified example of a B-Tree index (made up of 8K index and data pages) that can be used
to quickly look up all of the rows that have a customer number of 4 without having the need to scan every
row in the table. For this example, we are assuming that we have a B-Tree index on the customer number
column of the table, and that the data is sorted in ascending numerical order.
Notice that B-Trees have several levels. They include:

Root Level: A B-Tree starts with a single index page called the root level. This is where a
query begins to look for specific data within the B-Tree. In our example, our root level page
only contains two values. Most root level pages have many values, each referring to a
page in the intermediate level.
Intermediate Level: Most B-Trees have one or more intermediate levels. The number of
intermediate levels depends on the amount of data stored in the table being indexed. Our
example has only one intermediate level, which includes two index pages.
Leaf Level: A B-Tree has a single leaf level which may include many, many data pages,
depending on the amount of the data stored as part of the leaf level. The leaf level is
where the data you are looking for is stored. For example, in the leaf level page that starts
with 1, all the rows with a customer number that ranges from 1 through 2499 are
located. On the leaf level page that begins with 2500, all the rows that range from
2500 to 4999 are located, and so on.

Note: As we will learn later in this article, a clustered index stores all of the data of a row at the leaf level, while
a non-clustered index stores only the columns included in the index, along with a pointer to the related a row in
the clustered index. For the purposes of this example, we dont care if the index is clustered or non-clustered.
Heres how a B-Tree index works.
In a B-Tree index search, we always begin at the root level. For example, to find the rows that have a customer
number of 4, the first step is to scan the rows at the root level. In our example, there are two rows than can be
scanned: a 1 and a 5000. Each of these rows points to different pages in the intermediate level. The rows we
are seeking have a customer number of 4, but as you can see, there is no 4 at the root level. But since this
index is in numerical order, we know that 4 follows 1, but is less than 5000. So, to find the rows that have
a value of 4, we must hop down (transverse) to the intermediate level to further narrow our search. As you can
see in figure 2-6, the number 1 in the root level points to an index page in the intermediate level that also
starts with the number 1.
When we go to the intermediate level and look at the index page that begins with the number 1, notice that it
only has two records: a 1 and a 2500. Notice that the number 4 is still nowhere to be found. Again, we
know that the number 4 is greater than 1, but less than 2500, so we need to transverse to the leaf level and
see if we can find it there.
So the next step is to transverse the index to the leaf level page that begins with 1 and ends with 2499, as
we know that number 4 falls between these numbers. Once we are at the correct leaf level page, the rows in
this page are examined until we find one or more records that have a customer number of 4.
While this seems like a long way around to find the rows that have a customer number of 4, it is actually very
short. Instead of having to potentially scanning through thousands and thousands of data pages looking for the
rows to be returned, the query only had to scan through several different index pages until the rows that
matched the WHERE clause of the query are found and returned. This is usually a much faster way to find the
rows you want to return. Of course, this example was kept simple. In the real world, there may be more

47

intermediate levels that need to be transversed, but using a B-Tree index to retrieve data is usually much faster
than a scan of every row in a table.
Now that you have a basic understanding of how B-Tree indexes work, we are ready to talk about the specific
kinds of indexes available to SQL Server. Keep in mind that although each of the following indexes work
slightly differently, that are all still B-Tree indexes, and work on the principles described above.

Types of Indexes
SQL Server includes many different types of B-Tree indexes, including:

Clustered
Non-clustered

Indexed view

XML

Filtered (New with SQL Server 2008)

Spatial (New with SQL Server 2008)

Compressed Indexes (New to SQL Server 2008)

Note: SQL Server also offers full-text indexes, but they are beyond the scope of this article
Lets take a brief look at each of these index types.

Clustered
We have already talked about clustered indexes several times in this article. What I havent done until now is to
describe them in much detail. Technically speaking, a clustered index is a B-Tree data structure where all the
rows in a table are stored at the leaf level of the index. In other words, a clustered index not only includes the
root level and intermediate level index pages found in B-Tree indexes, it also includes all the data pages that
contain every row in the entire table. In addition, the rows in a clustered table are logically ordered by the key
selected for the clustered index (unlike a heap whose rows and pages are unordered). Because of this, a table
can only have one clustered index.

48

Figure 2-7: In a clustered index, the index and the data are one in the same. Rows are stored as the leaf pages
of a clustered index.
For example, lets say that we have a table called Customers that includes three columns: Customer Number,
First Name, and Last Name, and that the key for the clustered index is based on the Customer Number column.
Because this table has a clustered index, the entire row would be stored on a data page as part of the leaf level of
the B-Tree index. This is shown in figure 2-7, where we see that a particular row from that table is physically
stored on the leaf level page that begins with the letter 1. This page also holds additional rows, but they are
not shown here in this illustration in order to keep the example as simple as possible.
Because a clustered index is both an index and the rows of the table, whenever you execute a query against the
data using the key column as your selection criteria, you can quickly return the data because the data is part of
the index. All the query has to do is transverse the index until it finds the row data stored at the leaf level, and
return it. As we will learn in the next section, another type of index in SQL Server is called a non-clustered
index. In a non-clustered index, the index and the data rows are located in separate objects, which can often
contribute to additional resource use because now two objects, not just one, have to be touched by the query in
order to return the appropriate results.
As you might imagine, if a table has many rows, it will take many data pages to hold all of these rows at the leaf
level. To better facilitate this, data pages at the leaf level of a clustered index are kept in what is called a doubly
linked list, also called a page chain. See figure 2-8. The pages in the data chain, and the rows within each page,
are logically ordered based on the key. What does this mean to us?

49

Figure 2-8: Pages in a clustered index are connected to one another using a doubly-linked list (or page chain).
A pages page header includes nextPage and prevPage metadata, which is used to logically link one page to
another. While this illustration shows the pages as physically contiguous, they dont have to be.
Earlier, I said that a clustered index orders the data stored in it logically. Often, DBAs confuse logical ordering
with physical ordering. For example, what if a new row is added between two other rows, and there is no room
on the existing page for the new row? When SQL Server faces this problem, heres what it does. Once SQL
Server has determined more space is needed on a page, the page will be split. This means that about half of the
rows stay on the existing page and about half of the rows are added to a new page. The physical order of the
rows stays intact on the two pages, with the new row being place in the proper order on either the original or the
new page.
Think for a moment, if SQL Server required that all rows in a clustered index were to be physically contiguous,
then as part of the page split, the new page would have to be physically inserted directly after the original page,
and all of the following data pages would have to be shifted down one page. If there were 100,000 pages below
the page that was split, that would mean that 100,000 pages would have to be physically moved, which would
be hugely resource intensive and inefficient. Instead, what SQL Server does when a page split occurs, is to place
the new page where there is room for it, which in many cases wont be very close to the original page. In other
words, the physical order of the pages arent maintained. But what is maintained is the logical ordering of the
pages. For example, when a page is split between the original and the new page, they are logically connected
using the page chain, which is used to enforce the logical ordering of the data.
While the process described above keeps data in logical order, we can see that the logical order and the physical
order of the pages can get out of synch over time as data in the table changes. Is this a problem? Yes, it
potentially can be a big problem, and we will discuss this in great detail in article 3: What is Index
Fragmentation.
At this point, you should now realize that a table can take only two forms: a table without a clustered index (a
heap) or a table with a clustered index. As I explained earlier, for the purposes of this article, we are going to
assume that all tables have a clustered index.

Non-Clustered

50

Like a clustered index, a non-clustered index is a B-Tree data structure (although it is a separate data structure
from the clustered index). The main difference between the two is that while a clustered index includes all of
the data of a table at the leaf level, a non-clustered index does not. Instead, at the leaf level, a non-clustered
index includes the key value and a bookmark (pointer) that tells SQL Server where to find the actual row in the
clustered index.
Note: Besides the key value and a bookmark, the leaf level of a non-clustered index can also store non-key
columns, also referred to as included columns. Included columns are often added to non-clustered indexes to
create covering indexes.
Because a non-clustered index doesnt normally store the actual data at its leaf level, it is possible to have many
non-clustered indexes on a table. For example, a table can have one clustered index and up to 249 nonclustered index.
Lets take a brief look at how a non-clustered index works. In this example, we are going expand upon our
previous example of a Customer table that has three columns: Customer Number, First Name, and Last Name.
As in our previous example, we are going to have a clustered index that uses the Customer Number as its key.
In addition, we are going to add a non-clustered index on the Last Name column. Given this, lets say we want
to return all the rows (and all the rows columns) in the Customer Table that have a last name of Victoria, and
that we want to use the non-clustered index on the Last Name column to quickly find and return the data.
Heres what happens at the index level. See figure 2-9.

51

Figure 2-9: A non-clustered index must often work with a clustered index in order for all the selected data to be
returned by a query.
The first step in retrieving all of the rows with a Last Name of Victoria is to use the non-clustered index on
the Last Name column to identify any rows that match. To find the rows, SQL Server begins at the root level of
the non-clustered index, looking for any matching rows. The root page is scanned and two rows are found: an
A and an M. Each of these rows points to different pages in the intermediate level. The first letter of
Victoria is V, but there is no row in the root level page that begins with the letter V. But since this index
is in alphabetical order, we know that V follows M. So, to find the letter V, we must transverse to the
intermediate level to further narrow our search. As you can see in figure 2-9, the letter M points to an index
page in the intermediate level that starts with the letter M.
When we go to the intermediate level and look at the index page that begins with the letter M, notice that it
only has two records: an M and an S. Notice that the letter V is still nowhere to be found. Since we cant
find the letter V on this index page, we need to transverse to the leaf level and see if we can find it there.
Once we get to the leaf level page that begins with S, we now identify all the rows on that page that begin
with V. Each row that begins with V is then compared to the last name Victoria. In our case, there is a

52

single match. The last name Victoria is found in the Last Name non-clustered index key. Now we know that a
row does exist that meets our selection criteria, the problem is that all of the data for that row (Customer
Number, First Name, and Last Name) arent stored at the leaf level. Instead, the only data stored at the leaf level
is the key Victoria and a bookmark that points to the corresponding record in the tablewhich as we know
is a clustered index. In this example, the bookmark correspondents with the Customer Number 4.
Now that SQL Server knows that a row does exist, and that it exists in the clustered index as Customer Number
4, the actual contents of the row (the three columns) must be retrieved. So next, SQL Server must take the
bookmark value, the number 4, and then start at the root level of the clustered index, and then transverse the
intermediate and leaf level until it locates the matching row. At this point, the data is returned back the original
query. See figure 2-9.
As you can see, using a non-clustered index with a clustered index can be somewhat complex than using a
clustered index alone. But in the end, it is often much faster to retrieve rows from a table this way than by
scanning each one of them, one row at a time.

Indexed Views
As you probably know, a standard view is essentially a stored query. When you call a view in a Transact-SQL
statement, the underlying query is executed and results are returned. Often, views are referred to as virtual
tables because they do not exist until they are called. While views can be handy, the underlying query that
produces the view must be executed every time it is called, which can often require a lot of server resources to
be expended, especially if the view performs many joins or aggregations.
One potential away of avoiding the overhead of repeatedly re-executing the same standard view over and over
again is to create an indexed view. An index view is essentially a standard view that has been materialized as a
permanent object in the form of a clustered index, and can be accessed just as any other table can be accessed.
So once an indexed view is created, it physically exists, and when the indexed view is called, it does not have to
be re-executed because it already exists. This can offer a great performance boost if the same indexed views are
used over and over. If you like, non-clustered indexes can also be added to indexed views.
The downside of using an indexed view is that it stores physical data, so not only must the original tables (or
tables if the indexed view joins two or more tables) clustered index must be maintained as data is modified in
them, the clustered index that makes up the indexed view must also be maintained at the same time. If there is a
lot of data modification going on in the underlying tables, then maintaining an indexed view might use more
resources that it saves. This is a trade-off the DBA must evaluate when creating and using indexed views.
Although we wont spend much time on Indexed views in this article, they are included in this discussion
because they can become fragmented just like any index in SQL Server, and require regular maintenance in
order for them to perform optimally.

Computed Columns
SQL Server offers what are called computed columns. This is a virtual column in a row that is computed on the
fly when referenced by a query. In some occasions, it is useful to perform a search on a computed column.
While this works, the problem is that a scan has to be executed on the table because the computed values are not
materialized until they are touched by the query. This can greatly slow down the performance of a query that is
searching on a computed column.

53

If you find that you often need to perform a query on computed columns, one way to speed up performance is to
add an index on the computed column. When you add an index to a computed column, all the values for the
computed column become materialized as physical data. Because of this, the computed column can now be
queried like any column with an index, greatly boosting performance.
An index on a computed column is the equivalent of a non-clustered index, and as such, is subject to
fragmentation, and requires regular index maintenance so that it performs optimally over time.

XML
XML data in SQL Server is generally stored in XML data type columns in the form of Large Binary Objects
(LOBs) that can reach up to 2 GB in size. If you run a query against an XML data column (without an index),
the data has to be shredded before the query can parse the data to see if there is a match. Shredding, which
means converting the XML into a relational format, can be a time-consuming process that greatly hinders query
performance.
One way to avoid on-the-fly shredding, and to speed up queries against XML data, is to index your XML data
columns. SQL Server offers two different types of XML indexes.

Primary XML Index: When an XML index is created, the XML is shredded and
materialized in a physical form. In many ways, the resulting index is similar in concept to
an indexed view. In other words, the XML stored as a BLOB is converted to a relational
form that can easily be indexed and queried. If the XML data is large, adding a primary
XML index can take up a lot of space because all of the XML data is physically stored in its
shredded form.
Secondary XML Index: There are three different types of secondary XML indexes: PATH,
VALUE, and PROPERTY. These are created on the primary XML index, and in many ways,
are similar to adding a non-clustered index to an indexed view.

Like indexed views, adding primary and secondary XML indexes to a table can create a lot of overhead if there
is a lot of XML data modification occurring. This is because any changes to the original XML data column must
be reflected in the primary and secondary XML indexes. Like other SQL Server indexes, XML indexes can
become fragmented over time.

Filtered (New with SQL Server 2008)


A filtered index is a variation of a non-clustered index. While a non-clustered index indexes all of the rows in a
table, a filtered index only indexes those rows that you want indexed. In other words, you choose what rows you
want indexed (using a WHERE clause in your CREATE NONCLUSTERED INDEX command), and only those
rows that match your WHERE clause will be included as part of the filtered index.
The assumption you must make when creating filtered indexes is that there are queries that are run regularly
against your data that can make good use of them. For example, lets say you have a table, and that one of the
columns of this table has mostly NULL as its value. For the sake of this example, lets assume the table has
1,000,000 rows and that 900,000 of them have NULL as a value for the column. If you were to add a nonclustered index to this column, the index could potentially be very large, even though NULL is the most
common value. To continue with our example, lets also assume that you commonly run a query against this
table that uses this same column as part of the WHERE clause. While a non-clustered index will certainly speed
up the query, you still have a large index to deal with.

54

Now, lets consider the possibility of adding a filtered index on this column instead of a non-clustered index. If
you do this, then the index will only be built for the 100,000 rows that have a non-NULL value in them.
Because of this, the index is much smaller, and the overhead to use and maintain it are much less.
If you run a lot of queries against that are looking for non-NULL values, then this filtered index can be very
useful. On the other hand, if you create such a filtered index, and are looking for NULL values, then the filtered
index would not be used. As you can imagine, you will have to carefully consider the queries you are running in
order to identify those columns that could be best served by adding a filtered index.
Filtered indexes are best used on columns that can contain easily be divided into well-defined subsets. For
example:

Columns that contain few values, but many NULL, such as in the example above.
Columns that have heterogeneous data, such as a column that stores the color of a
product. For example, green, red, blue, and so on.

Columns that contain ranges of values, such as time, date, money, and so on.

Columns that have data that can be easily defined using comparison logic within a WHERE
clause

Now, you may be asking, what are the benefits of using filtered indexes? One major benefit is that filtered
indexes also use filtered statistics. Filtered statistics are more accurate than non-filtered statistics, and as a
result, the quality of query execution plans often occurs, helping to boost query performance. Second, because
fewer rows are indexed, when data modifications occur, there is less overhead when maintaining the filtered
index, as compared to a non-clustered index. Third, smaller indexes use up less space, saving storage costs. And
forth, smaller indexes take less time to rebuild.
As with any non-clustered index, filtered indexes can become fragmented over time, and need periodic
maintenance.

Spatial (New with SQL Server 2008)


Spatial indexes can be created on either geometry or geography spatial columns. Before a spatial index can be
created as a B-Tree structure, spatial data has to be decomposed into a grid hierarchy. This is because a spatial
index refers to finite space. For example, an index on a geometry data column could map an area on a plane,
and an index on a geography column could map geographic data to a two-dimensional space.
In some ways, this decomposing is similar to how XML data needs to be shredded before it can be indexed
(although this is a much different process). How this is done is beyond the scope of this article, but what is
important to remember is that spatial indexes, like all SQL Server B-Tree indexes, need regular maintenance.

Compressed (New with SQL Server 2008)


In SQL Server 2008, there is no special compressed index type. What I am referring to in this section is the
ability in SQL Server 2008 (Enterprise Edition) to perform compression on clustered indexes, non-clustered
indexes, and indexed views. Compression comes in two forms:

Row-level Data Compression: Row-level data compression is essentially turning fixed


length data types into variable length data types, freeing up empty space. It also has the
ability to ignore zero and null values, saving additional space. In turn, more rows can fit
into a single data page.

55

Page-level Data Compression: Page-level data compression starts with row-level data
compression, then adds two additional compression features: prefix and dictionary
compression, providing for greater compression than row-level compression alone.

While two types of data compression are available, this is only available for the leaf level pages of an index.
The root and intermediate levels of an index can only be compressed using row-level compression.
The reason I mention compressed indexes here is several fold. First, turning on compression can in some cases
reduce fragmentation (a DELETE on a clustered index), and it other cases, it can make it worse (if an UPDATE
causes a page split on clustered index) than without using compression in the first place. In addition, turning on
compression can significantly add to the overhead required to maintain indexes. Because of this, if you use
compressed indexes, you need to keep these implications in mind.

Summary
In this article, we learned the basics of SQL Server indexing. Not only did we answer the questions: What is a
table? and What is an Index? we described all the different types of indexes available in SQL Server. One of
the most important things you should get out of this article is that all SQL Server indexes are B-Trees, no matter
what kind of data they hold. In addition, each of these types of indexes are subject to fragmentation, which
would be a subject for a article in its' own right

Upgrading SQL Server


1. Can you upgrade SQL Server 2008 SP2 Standard Edition to 2008 R2 Developer Edition?

56

Ans:
You cant change the version of the installed instance as far as I know, but you could install a second instance
with the Dev edition, or uninstall the Standard edition, install Developer edition and attach the user databases.
2. Does upgrade advisor analyze the remote instances?
Ans:
Upgrade Advisor can analyze remote instances of SQL Server, except for SQL Server Reporting Services. To
analyze Reporting Services, Upgrade Advisor must be installed and executed on the report server.
3. Ho to upgrade a SQL Server 2000 to SQL Server 2008?
Ans:
That said, what kind of upgrade are you doing? Are you planning an in-place or side-by-side upgrade? The
different approaches will result in different checklists. The safest approach is the side-by-side upgrade. You can
do this either by using a backup and restore or dettach/attach of the database files. Id suggest using the backup
& restore as the safer approach. Here are the things Id do:

Run Upgrade Analysis tool from Microsoft. Address any issues raised there, first.
Identify DTS packages. These must be migrated by hand, unless you buy PragmaticWorks
excellent software. Rebuild the DTS packages as SSIS.

Script out all SQL Agent jobs.

Script out all security

Backup the systems and validate the backups (preferably by restoring them to another
system)

Run the security script on the new system

Run the restore on the new system.

Validate the databases by running DBCC

Manually update all statistics

Run the SQL Agent script

4. Have you ever prepared a checklist while performing an upgrade?


Ans:
Yes Of course!!!

Identify which databases need to be upgraded (ie are still on older versions of SQL Server)
Of those databases, which are not supported on more recent versions of SQL Server? This
is one for the appropriate vendor so do we have contact details for the vendor?

57

Of those non-supported databases, if this is just because the vendor hasnt tried it, are we
able to try and will they support is in our efforts?

Identify maintenance routines and scheduled jobs associated with database

Identify dependencies upon older technologies (eg DTS rather than SSIS), and work out an
upgrade path for these

What applications depend upon the database?

What UserIDs are required?

How do we configure the application to point to a new database?

What else needs to be changed? (eg middleware servers)

Are parts of the database subject to Replication?

Is the database part of a Log Shipping routine?

Is the database part of a Mirror set?

Whats the recovery plan for the database?

Whats the backup plan for the database?

Are there any SSRS jobs relating to this database?

What are they?

Where are they?

How do we migrate these across?

What else depends upon those reports?

and similarly, are there any OLAP / SSAS dependencies?

It might also be worth thinking about the amount of data in the database:

How much data have we got?


How fast is the database growing?

For how long do we need to retain this data?

Can we archive anything off to improve performance?

Of course, all the above forms part of your database documentation, so it should be easily to hand, right?
The other things to work out include:

How do we test this thing to ensure the migration is successful?


How do we rollback if it isnt successful?

Point of contact for the supplier / vendor / development team

Point of contact for the customer(s) / user(s)

58

5. Can you detach a SQL Server 2005 database and attach it to a SQL Server 2008 server?
Ans:
Yes. SQL Server 2005 databases are compatible with SQL Server 2008. However, that attaching a SQL Server
2005 database to SQL Server 2008 automatically upgrades the SQL Server 2005 database to a SQL Server 2008
database and the database is then no longer usable by the SQL Server 2005 installation.
6. Can you detach a SQL Server 2008 database and attach it to a SQL Server 2005 server?
Ans:
No. The only way to move a SQL Server 2008 database to a SQL Server 2005 server is by transferring the data
using a method such as Data Transformation Services (Import/Export),SSIS, bcp, or use of a query between
linked servers.
7. How long will it take to upgrade my SQL Server databases?
Ans:
Many factors affect the amount of time needed to upgrade SQL Server Databases. Depending on the complexity
of each database, Size of databases, the hardware platform, number of processors, disk subsystem, and amount
of RAM plays a significant part in the amount of time required for the upgrade. Selecting data validation
during the setup increases the amount of time needed to perform the upgrade by a factor of two. Some typical
times for the upgrade process are:
Size of
Database

Estimated Time Required


to Upgrade

400 MB

Less than 20 minutes.

1 GB

Less than 1 hour.

10 GB

Less than 4 hours.

50 GB

Less than 12 hours.

100 GB

Less than 24 hours.

8. When you upgrade a SQL Server, the upgrade wizard seems to stop responding and fails. Why?
Ans:
If applications or services have open ODBC connections to the SQL Server 2005 server during the conversion
process, they may not allow the SQL Server to shut down completely. The conversion process will not proceed
on to the next step if it does not receive verification that the SQL Server has been completely stopped.
9. Im trying to restore a 25 GB database backup taken from a Windows 2003/SQL 2005 machine to a
Windows 2008/SQL 2008 machine in the Amazon EC2 cloud, using a .bak file and the SQL Management
Studio. SQL Management Studio reports the restore reaches 100% complete, and then just hangs
indefinitely (24+ hours) using a lot of CPU, until I restart the SQL Server service. Upon restart, SQL

59

again uses a lot of CPU activity for what seems to be an indefinite amount of time, but the DB never
comes online.
Ans:
The database is in the process of being upgraded from SQL 2005 to SQL 2008 when you kill it. Check the
ERRORLOG in SQL Server and you should see that the database restore is complete and that the database is
being upgraded.
This process is normally very quick, but it can take a while to perform depending on the database, especially if
you have a lot of pending transactions in the database which much be rolled forward or backward before the
database can be upgraded.
9. How to rollback the upgrade?
Ans:
If the legacy SQL Server instance is replaced by a new SQL Server 2008 instance, rolling back an in-place
upgrade can be complex and time-consuming, whereas in a side-by-side upgrade the legacy instance remains
available if a rollback is needed.
10. What are the different ways in upgrading to a higher version?
Ans:
There are two ways:
In-Place Upgrade: Installs 2008 and overwrite on the 2005 Server.
Side-by-side Upgrade: A new instance will be installed and moves the databases.
11. Give some examples when we consider Side-by-side and In-Place?
Ans:
Pros & Cons: In-Place
Pros

Easier, mostly automated


Generally fast overall process

Requires no additional hardware

Applications remain pointing to same server/database name

Cons

Less granular control over upgrade process


Instance remains offline during part of upgrade

60

Not best practice for all components

Complex rollback strategy

Not recommended for SSAS

Pros & Cons: Side-by-side:


Pros

More granular control over the upgrade process


Original database left unchanged; allows for testing of new database

Single occurrence of database downtime

Relatively straightforward rollback strategy

Cons:

Usually require additional hardware


Server/database name changes

Not practical for VLDB unless utilizing SAN(Beware of loss of quick roll-back)

12 What are the parameters should be considered while choosing the upgrade process?
Ans:
Components: A certain upgrade strategy might not be possible because the component does not support it. For
example, there is no in-place upgrade for SSIS from SQL Server 2000; Microsoft recommends that you upgrade
most SQL Server 2000 SSAS components.
Versions and Editions: The in-place upgrade strategy does not support all paths between versions and editions.
For example, to upgrade a SQL Server 2000 Enterprise Edition instance to SQL Server 2008 Standard Edition,
you must perform a side-by-side upgrade because SQL Server Setup does not support an in-place upgrade path.
Partial upgrading: To transition only a few databases on a server to SQL Server 2008 and leave the rest on the
legacy version, you must use a side-by-side upgrade.
Upgrading over time: To transition databases gradually, a few databases at a time, from a legacy instance to
SQL Server 2008, you can only use a side-by-side upgrade.
Effect on applications: If your organization requires minimal disturbance to the existing applications and users,
you may want to choose an in-place upgrade if possible.
Availability: Both an in-place upgrade and a side-by-side upgrade require that the databases be unavailable for
a certain amount of time. The amount of downtime required depends primarily on the size of the data sets. At
first, it might seem that an in-place upgrade would be faster than a side-by-side upgrade because the data is not
transferred from one server to another. However, an in-place upgrade also requires time for the installation of
SQL Server 2008. In a side-by-side upgrade, SQL Server 2008 is already installed on another instance. If the

61

data transfer proceeds quickly and few changes are needed on the new instance, a side-by-side upgrade might be
faster than an in-place upgrade.
13. We have upgraded databases from SQL Server 2000 to SQL Server 2008 and now the upgrade hits
the production. Unfortunately a part of application is not supporting SQL Server 2008. Do we need to
Rollback entire process to SQL 2000? Is that the only solution? If it is the only way! Since the databases
at production transactions are being running and the data has been updated. Please assist us.
Ans
However, after the upgraded SQL Server 2008 instance goes into production and starts capturing new data,
there will come a point in time when enough new data has been captured that a rollback is no longer realistic.
For an in-place upgrade, if you encounter problems after the system is in production, making adjustments or
patches to the new application would be a better option than attempting a rollback. For a side-by-side
upgrade, you could employ SSIS to transfer new data from the SQL Server 2008 instance to the legacy SQL
Server 2000 to bring it current. Depending on the complexity of the data, this could be a difficult process.
14. Can you list out some of the compatibility options while upgrading?
Ans:
For example we goanna upgrade SQL 2000 to SQL 2008:

Some features do not exist anymore


Examples: undocumented system stored procedures, DUMP, LOAD, sp_addalias,

Some are deprecated, Will be removed in future versions of SQL Server

Examples: SQL Mail, COMPUTE BY, Remote Servers, backup passwords,

Some features behave differently

Example: Access to catalog views (new security on system views)

Some editions have different features

Example: Express has no SQL Server Agent

15. What are the different tools available while upgrading from SQL 2000 to SQL 2008?
Ans:
Primary Tools:

SQL Server 2008 Upgrade Advisor


DTS xChange

Secondary Tools

Microsoft Assessment and Planning Toolkit 3.2

62

SQL Server 2008 Upgrade Assistant

SQL Server Best Practices Analyzer

System Configuration Checker

SQL Server Profiler

SQL Server: Deprecated Features Object Counter

Other tools

16. Error while upgrading to SQL server 2005 from Sql server 2000.
while upgrading my sqlserver 2000 with version 8.0.2039 to SQLserver 2005, msxml6.msi failed to
upgrade and while trying to uninstall it is try to look the msi file which missing from the path
Ans:
MSXML 6 services installed in my server is a lower version of SP2 msxml6-KB954459 and not allowing the
upgrade, because setup trying to upgrade MSXML6.MSI and it could not locate the file in the previous
installation and Of course it got missed.
So, we have worked out here to download the same version from Microsoft website and then extracted the
MSXML6.MSI file to some location and then we tried to un-install the MSXMl service and it went
successfully.
Later, again we have installed the msxml6-KB954459-enu-x86.exe and upgrade of SQLserver 2000 to 2005
went smooth without issues and applied latest servicepack 4 successfully.
17. How to Upgrade to SQL SERVER 2005?
Ans:

We can directly upgrade instances of SQL Server 2000 Service Pack 3 (SP3) or later, and
instances of SQL Server 7.0 SP4 or later, to SQL Server 2005. We can perform most
upgrade operations through Setup
Before running Setup to upgrade to SQL Server 2005, we should first review system
requirements and update Matrix

Before beginning an upgrade

All SQL Server database files will have to be backed up.

Appropriate DBCC commands should be run to ensure consistent state.

SQL Server System databases will have to be configured with autogrow setting to ensure
that they will have adequate disk space.

All startup procedures will have to be disabled; else they will block the process of
upgrading.

Replication log should be emptied and Replication will have to be stopped.

63

Another factor that needs to be taken into account while preparing for an upgrade, are the
features that have been deprecated in SQL Server 2005.

Once all the above has been done, SQL Server 2005 setup has to be run and the instance
installed.

The upgrade Advisor does not get installed automatically when SQL Server is installed. It
has to be installed separately.

After reviewing system requirements and upgrade Matrix, run SQL Server Upgrade Advisor
to analyze the instances of SQL Server 2000 and SQL Server 7.0.

Upgrade Advisor produces lists of issues that we must fix before or after upgrading. SQL
Server Setup will detect blocking issues that will prevent us from upgrading to SQL Server
2005 (The table alias should not be used in order by clause)

Thereafter, move user databases to the instance by using backup and restore or detach
and attach functionalities in SQL Server 2005. Then register the server, repopulate full text
catalogs, update the statistics and run Surface Area Configuration tool. Change the
compatibility level to 90 from 80

18. What are the issues u faced in sql server upgrade?


Ans:
Common causes

SQL Server or the machine running the upgrade loses its network connection.
The database in which you were working has run out of log or data space.

You are not allowed to perform an update to a table.

The database is corrupted.

The database is not available (still in recovery.) It may be unavailable if the upgrade
program begins to work before SQL Server finishes performing recovery after startup.

Unable to restart the server

Can identify the issue from the upgrade log files and resolve the issues and rerun the upgrade advisor
19. What is the sequence to install service packs or hotfixes on an instance of SQL Server that is part of
Log Shipping/Database Mirroring/Replication/Failover Clustering environment?
Ans:
When an instance of SQL Server is configured as part of Log Shipping, Database Mirroring, Replication, or
Failover Clustering environment, it is important to install service packs or hotfixes in a correct sequence
otherwise we may get unexpected issues.
Log Shipping:

64

There is no required sequence to apply a service pack or hotfix for Primary, Secondary and Monitor servers in a
Log Shipping environment. The following is my preferable to apply service pack or hotfix:

Apply the service pack or hotfix on the Monitor server.


Apply the service pack or hotfix on the all Secondary servers.

Apply the service pack or hotfix on the Primary server.

Database Mirroring:
If you install service packs or hotfixes on servers in a database mirroring environment, you need to determine
the role of the servers. If there are many mirroring sessions configured on the server, you need to determine all
possible roles that could be. For instance, if the server is acting as a mirror server for any database mirroring
session, update the server as the mirror role for all mirroring sessions. To do this, follow these steps:

If a witness server is configured in the database mirroring session, disable the automatic
failover during the update process. To do this, remove the witness server from the
mirroring session.
If the safety level of the database mirroring session is OFF (asynchronous mode), change
the safety level to FULL (this is required in step 3).

Make sure all database mirroring sessions to be in Synchronous mode and synchronized.

Pause the database mirroring sessions that are present on the server.

Install the service pack or hotfix on the mirror server.

Resume the database mirroring sessions.

Perform manual failover (all the mirroring sessions on this principal server) to the mirror
server so that mirroring server assumes the principal role.

Pause the database mirroring sessions as step 4.

Install the service pack or hotfix on the new mirror server (previous principal server).

Resume the database mirroring sessions.

If you changed the safety level in step 2, change the safety level back to OFF.

If the database mirroring session has a witness server, undo the changes made in step 1.

Replication:
In a replication environment, there is no preferable sequence to apply service pack or hotfix for nonbidirectional replication typology. However, for bi-directional replication typology such as merge typology or
transactional replication with updateable subscriptions, you must upgrade Distributor, Publisher, and
Subscribers in the following order:

Apply the service pack or hotfix on the Distributor server.


Apply the service pack or hotfix on the Publisher server.

Apply the service pack or hotfix on the Subscriber server.

65

Failover Clustering:
In SQL Server 2005, if you want to install a service pack or hotfix, you must install the setup on the Active node
(node that currently runs SQL Server services). When running the setup which will launch simultaneously
remote silence on all passive nodes.
However, in SQL Server 2008 and SQL Server 2008 R2, the service pack or hotfix deployment is changed to
reduce the downtime. Now, you must install the service pack or hotfix on the passive node first. To do this,
following these steps:

Apply the service pack or hotfix on the passive node (or all passive nodes if you have more
than one).
Reboot the passive node.

Failover the SQL Server failover cluster to the passive node (and the passive node
becomes active now).

Apply the service pack or hotfix on the new passive node (previous active node).

Reboot the passive node.

66

Concurrency Control And Locking

Concurrency and Locking Interview Questions with answers

67

1. What are the concurrent problems occur in accessing database?


Ans:
Tr Transaction
R Resource
Uncommitted dependency/dirty reads:
Tr1 Updates Data R1
Tr2 Reads Data R1
Tr1 Rollback the Update Operation R1
Now Tr2 has the inconsistent data or wrong data.
Inconsistent Analysis/non-repeatable reads
Tr1 Reads Data R1
Tr2 Updates Data R1
Tr1 Again Reads the same data R1
Wrong match between first Tr1 and Second time Tr1
Phantom reads (via insert/delete)
Tr1 Reads Data (Result Contains 10 Records R1
Tr2 Insert/Delete Data (insert 6 new delete 1 Record) R1
Tr1 Again reads the same data R1
In Second time Tr1 we found 6 New Records and we cant find a record which retrieves in first time..
2. What isolation levels will provide completely read-consistent views of a database to all transactions?
Ans:
SQL Server 2000: Only the SERIALIZABLE isolation level will provide a completely read-consistent view of
a database to a given transaction. In any of the other isolation levels, you could perceive some/all of the
following, depending on the isolation level running in:

Uncommitted dependency/dirty reads

Inconsistent Analysis/non-repeatable reads

68
o

Phantom reads (via insert/delete)

SQL Server 2005 and above: Both the SERIALIZABLE and SNAPSHOT isolation levels will provide a
completely read-consistent view of a database to a given transaction. In any of the other isolation levels, you
could perceive some/all of the following, depending on the isolation level running in:

Uncommitted dependency/dirty reads

Inconsistent Analysis/non-repeatable reads

Phantom reads (via insert/delete)

3. Within the READ_COMMITTED isolation level, during a read operation how long are locks
held/retained for?
Ans:
When SQL Server executes a statement at the read committed isolation level, it acquires short lived share locks
on a row by row basis. The duration of these share locks is just long enough to read and process each row; the
server generally releases each lock before proceeding to the next row. Thus, if you run a simple select statement
under read committed and check for locks, you will typically see at most a single row lock at a time. The sole
purpose of these locks is to ensure that the statement only reads and returns committed data. The locks work
because updates always acquire an exclusive lock which blocks any readers trying to acquire a share lock.
4. Within the REPEATABLE_READ and SERIALIZABLE isolation levels, during a read operation and
assuming row-level locking, how long are locks held/retained for?
Ans:
Within either of these isolation levels, locks are held for the duration of the transaction, unlike within the
READ_COMMITTED isolation level as noted above.
5. Can locks ever be de-escalated?
Ans:
No, locks are only escalated, never de-escalated.
6. What are the different types of lock modes in SQL Server?
Ans:

Shared
Update

Exclusive

Schema (modification and stability)

Bulk Update

69

Intent (shared, update, exclusive)

Key Range (shared, insert, exclusive)

7. Can you explain scenarios where each type of lock would be taken?
Ans:
SHARED: Used for read operations that do not change or update data, such as a SELECT statement.
UPDATE: Update locks (U) are acquired just prior to modifying the data. If a transaction modifies a row, then
the update lock is escalated to an exclusive lock; otherwise, it is converted to a shared lock. Only one
transaction can acquire update locks to a resource at one time. Using update locks prevents multiple connections
from having a shared lock that want to eventually modify a resource using an exclusive lock. Shared locks are
compatible with other shared locks, but are not compatible with Update locks.
EXCLUSIVE: Used for data-modification operations, such as INSERT, UPDATE, or DELETE. Ensures that
multiple updates cannot be made to the same resource at the same time.
INTENT: Used to establish a lock hierarchy. The types of intent locks are: intent shared (IS), intent exclusive
(IX), and shared with intent exclusive (SIX). (Another question in the Difficult level section expands on this)
SCHEMA: Used when an operation dependent on the schema of a table is executing. The types of schema
locks are: schema modification (Sch-M) and schema stability (Sch-S).
BULK UPDATE: Used when bulk copying data into a table and the TABLOCK hint is specified.
KEY RANGE: Protects the range of rows read by a query when using the serializable transaction isolation
level. Ensures that other transactions cannot insert rows that would qualify for the queries of the serializable
transaction if the queries were run again.
8. What is lock escalation and what triggers it?
Ans:
The process of converting many fine-grained locks into fewer coarse-grained locks is known as Lock
Escalation.
** Escalation reduces system resource consumption/overhead while increasing the possibility of concurrency
conflicts
**To escalate locks, the Database Engine attempts to change the intent lock on the table to the corresponding
full lock, for example, changing an intent exclusive (IX) lock to an exclusive (X) lock, or an intent shared (IS)
lock to a shared (S) lock). If the lock escalation attempt succeeds and the full table lock is acquired, then all
heap or B-tree, page (PAGE), key-range (KEY), or row-level (RID) locks held by the transaction on the heap or
index are released. If the full lock cannot be acquired, no lock escalation happens at that time and the Database
Engine will continue to acquire row, key, or page locks.
**Lock escalation is triggered at either of these times:

70

When a single Transact-SQL statement acquires at least 5,000 locks on a single table or
index.
When the number of locks in an instance of the Database Engine exceeds memory or
configuration thresholds.
If locks cannot be escalated because of lock conflicts, the Database Engine periodically
triggers lock escalation at every 1,250 new locks acquired.

9. Name as many of the lockable resources as possible in SQL Server?


Ans:

RID (single row on a heap)


KEY (single row (or range) on an index)

PAGE

EXTENT

HOBT (heap or b-tree)

TABLE (entire table, all data and indexes)

FILE

APPLICATION

METADATA

ALLOCATION_UNIT

DATABASE

10. What requirements must be met for a BULK-UPDATE lock to be granted, and what benefit do they
server?
Ans:
The Database Engine uses bulk update (BU) locks when bulk copying data into a table, and either the
TABLOCK hint is specified or the table lock on bulk load table option is set using sp_tableoption. Bulk update
(BU) locks allow multiple threads to bulk load data concurrently into the same table while preventing other
processes that are not bulk loading data from accessing the table.
11. What is the least restrictive type of lock? What is the most restrictive?
Ans:
The least restrictive type of lock is a shared lock. The most restrictive type of lock is a schema-modification
12. What is a deadlock and how is it different from a standard block situation?
Ans:

71

A deadlock occurs when two or more tasks permanently block each other by each task having a lock on a
resource which the other tasks are trying to lock. In a deadlock situation, both transactions in the deadlock will
wait forever unless the deadlock is broken by an external process in a standard blocking scenario, the blocked
task will simply wait until the blocking task releases the conflicting lock scenario.
13. Which 2 isolation levels support optimistic/row-versioned-based concurrency control?
Ans:
First is the READ COMMITTED isolation level. This is the only level that supports both a pessimistic
(locking-based) and optimistic (version-based) concurrency control model. Second is SNAPSHOT isolation
level that supports only an optimistic concurrency control model.
14. What database options must be set to allow the use of optimistic models?
Ans:
READ_COMMITTED_SNAPSHOT option for the read committed optimistic model.
ALLOW_SNAPSHOT_ISOLATION option for the snapshot isolation level
15. What is the size of a lock structure?
Ans:
96 bytes
16. In what circumstances will you see key-range locks, and what are they meant to protect against?
Ans:
You will only see key-range locks when operating in the SERIALIZABLE isolation level.

Key-range locks protect a range of rows implicitly included in a record set being read by a
Transact-SQL statement. The serializable isolation level requires that any query executed
during a transaction must obtain the same set of rows every time it is executed during the
transaction. A key range lock protects this requirement by preventing other transactions
from inserting new rows whose keys would fall in the range of keys read by the serializable
transaction.
Key-range locking prevents phantom reads. By protecting the ranges of keys between
rows, it also prevents phantom insertions into a set of records accessed by a transaction.

17. Explain the purpose of INTENT locks?


Ans:
The Database Engine uses intent locks to protect placing a shared (S) lock or exclusive (X) lock on a resource
lower in the lock hierarchy. Intent locks are named intent locks because they are acquired before a lock at the
lower level, and therefore signal intent to place locks at a lower level. Intent locks serve two purposes:

72

To prevent other transactions from modifying the higher-level resource in a way that would
invalidate the lock at the lower level.
To improve the efficiency of the Database Engine in detecting lock conflicts at the higher
level of granularity.

18. Can deadlocks occur on resources other than database object?


Ans:
YES.
19. What are the different types of resources that can deadlock?
Ans:
Deadlock is a condition that can occur on any system with multiple threads, not just on a relational database
management system, and can occur for resources other than locks on database objects. Here are the resources:
Locks Waiting to acquire locks on resources, such as objects, pages, rows, metadata, and applications can
cause deadlock.
Worker threads A queued task waiting for an available worker thread can cause deadlock. If the queued task
owns resources that are blocking all worker threads, a deadlock will result
Memory When concurrent requests are waiting for memory grants that cannot be satisfied with the available
memory, a deadlock can occur.
Parallel query execution-related resources Coordinator, producer, or consumer threads associated with an
exchange port may block each other causing a deadlock usually when including at least one other process that is
not a part of the parallel query. Also, when a parallel query starts execution, SQL Server determines the degree
of parallelism, or the number of worker threads, based upon the current workload. If the system workload
unexpectedly changes, for example, where new queries start running on the server or the system runs out of
worker threads, then a deadlock could occur.
Multiple Active Result Sets (MARS) resources Resources used to control interleaving of multiple active
requests under MARS, including:

User resource when a thread is waiting for a resource that is potentially controlled by a
user application, the resource is considered to be an external or user resource and is
treated like a lock
Session mutex The tasks running in one session are interleaved, meaning that only one
task can run under the session at a given time. Before the task can run, it must have
exclusive access to the session mutex.
Transaction mutex All tasks running in one transaction are interleaved, meaning that
only one task can run under the transaction at a given time. Before the task can run, it
must have exclusive access to the transaction mutex.

20. Explain how the database engine manages the memory footprint for the lock pool when running in a
dynamic lock management mode.

73

Ans
SQL Server 2000: When the server is started with locks set to 0, the lock manager allocates two percent of the
memory allocated to SQL Server to an initial pool of lock structures. As the pool of locks is exhausted,
additional locks are allocated. The dynamic lock pool does not allocate more than 40 percent of the memory
allocated to SQL Server.

Generally, if more memory is required for locks than is available in current memory, and
more server memory is available (the max server memory threshold has not been
reached), SQL Server allocates memory dynamically to satisfy the request for locks.
However, if allocating that memory would cause paging at the operating system level (for
example, if another application was running on the same computer as an instance of SQL
Server and using that memory), more lock space is not allocated.

SQL Server 2005: When running in dynamic management mode (i.e. if the server is started with locks
configuration option set to 0), the lock manager acquires sufficient memory from the Database Engine for an
initial pool of 2,500 lock structures. As the lock pool is exhausted, additional memory is acquired for the pool.

Generally, if more memory is required for the lock pool than is available in the Database
Engine memory pool, and more computer memory is available (the max server memory
threshold has not been reached), the Database Engine allocates memory dynamically to
satisfy the request for locks. However, if allocating that memory would cause paging at
the operating system level (for example, if another application is running on the same
computer as an instance of SQL Server and using that memory), more lock space is not
allocated. The dynamic lock pool does not acquire more than 60 percent of the memory
allocated to the Database Engine. After the lock pool has reached 60 percent of the
memory acquired by an instance of the Database Engine, or no more memory is available
on the computer, further requests for locks generate an error.

21. Describe the differences between the pessimistic SERIALIZABLE model and the optimistic
SNAPSHOT model in terms of transactional isolation (i.e., not the concurrency differences, but instead
how the exact same transactional modifications may result in different final outcomes).
Ans:
It is typically relatively simple to understand SERIALIZABLE. For the outcome of two transactions to be
considered SERIALIZABLE, it must be possible to achieve this outcome by running one transaction at a time in
some order.

Snapshot does not guarantee this level of transactional isolation.


Imagine the following sample scenario:

Serializable:
There is a bag containing a mixture of white and black marbles. Suppose that we want to run two transactions.
One transaction turns each of the white marbles into black marbles. The second transaction turns each of the
black marbles into white marbles. If we run these transactions under SERIALIZABLE isolation, we must run
them one at a time. The first transaction will leave a bag with marbles of only one color. After that, the second
transaction will change all of these marbles to the other color. There are only two possible outcomes: a bag with
only white marbles or a bag with only black marbles.

74

Snapshot:
If we run these transactions under snapshot isolation, there is a third outcome that is not possible under
SERIALIZABLE isolation. Each transaction can simultaneously take a snapshot of the bag of marbles as it
exists before we make any changes. Now one transaction finds the white marbles and turns them into black
marbles. At the same time, the other transactions finds the black marbles but only those marbles that where
black when we took the snapshot not those marbles that the first transaction changed to black and turns them
into white marbles. In the end, we still have a mixed bag of marbles with some white and some black. In fact,
we have precisely switched each marble.
22. What are the different isolation levels available?
Ans:

Read Uncommitted Isolation Level


Read Committed Isolation Level

Repeatable Read Isolation Level

Serializable Isolation Level

Snapshot Isolation Level

Read Committed Snapshot Isolation Level

23. Demonstrate Isolation levels?


Ans:

Read Uncommitted: This is the lowest isolation level. It only isolates transactions and
activities to ensure that physically corrupt data is never read. It allows dirty reads,
nonrepeatable reads, and phantom reads.
Read Committed: This isolation level does not permit dirty reads, but does allow
nonrepeatable reads and phantom reads. This is the default isolation level for SQL Server,
and is used for each connection to SQL Server unless one of the other isolation levels has
manually been set for a connection.

Repeatable Read: This isolation level does not permit dirty reads or nonrepeatable
reads, but does allow phantom reads.

Serializable Read: This is the highest isolation level and ensures that all transactions
and statements are completely isolated from each other. It does not allow dirty reads,
nonrepeatable reads, or phantom reads.

New isolation levels that introduced in SQL 2005 based on row versioning:

READ_COMMITTED_SNAPSHOT (statement level): READ_COMMITTED_SNAPSHOT is


actually a variation of the default READ_COMMITTED isolation level. It uses row versioning,
instead of locking, to provide read consistency at the SQL Server statement level. When a
statement runs that specifies the READ_COMMITTED isolation level (the default isolation
level), and the READ_COMMITTED_SNAPSHOT option is turned on at the database level, all

75

statements see a snapshot of the data as it existed at the start of any current transaction.
It uses the row-versioned snapshot of the row to return data, and no locking is needed by
the statement, which is normally the case. The biggest benefit of this isolation level is that
reads do not block writes and writes do not block reads. Writes can still block writes, but
this is necessary to prevent data corruption.
ALLOW_SNAPSHOT_ISOLATION (transaction level): ALLOW_SNAPSHOT_ISOLATION is
similar to READ_COMMITTED_SNAPSHOT, but it is based at the transaction level, not the
statement level. When the ALLOW_SNAPSHOT_ISOLATION is turned on at the database
level and the TRANSACTION ISOLATION LEVEL SNAPSHOT isolation level is turned on for
the transaction (using the SET command), all statements see a snapshot of the data as it
existed at the start of the transaction.

24. Any idea about row versioning?


Ans:
The concept of row versioning is not new to SQL Server, as SQL Server has been using it for years with
triggers. For example, when a DELETE trigger is executed for a row, a copy of that row is stored in the deleted
table just in case the trigger is rolled back and the deleted row needs to be undeleted. In a sense, the row is
versioned, and if need be, can be reused.
Row versioning for isolation levels is very similar, though not identical to row versioning for triggers. When a
row versioning-based isolation level (which includes the two new ones we are now discussing) is enabled at the
database level, the database engine maintains versions of each row that is modified (for an entire database).
Whenever a transaction modifies any row, an image of the row before the modification is copied into a page of
what is called the version store. The version store is located in the tempdb database and is used for temporary
storage of versioned rows for all of the databases on a single SQL Server instance.
25. What are the properties of a transaction?
Ans:
There are 4 properties called ACID.
Atomicity: All changes to data are performed as if they are a single operation. That is, all the changes are
performed, or none of them are.
Example: In an application that transfers funds from one account to another, the atomicity property ensures
that, if a debit is made successfully from one account, the corresponding credit is made to the other account.
Consistency: Data is in a consistent state when a transaction starts and when it ends.
Example: In an application that transfers funds from one account to another, the consistency property ensures
that the total value of funds in both the accounts is the same at the start and end of each transaction.
Isolation: The intermediate state of a transaction is invisible to other transactions. As a result, transactions that
run concurrently appear to be serialized.
Example: in an application that transfers funds from one account to another, the isolation property ensures that
another transaction sees the transferred funds in one account or the other, but not in both, nor in neither.

76

Durability: After a transaction successfully completes, changes to data persist and are not undone, even in the
event of a system failure.
Example: in an application that transfers funds from one account to another, the durability property ensures that
the changes made to each account will not be reversed.
26. How to find out and prevent Deadlocks?
Ans:
To find Deadlocks
Error:
Transaction (Process ID 52) was deadlocked on lock resources with another process and has been chosen as the
deadlock victim. Rerun the transaction.
There are two popular ways to identifying the deadlocks

Enabling a Trace Flag


By default Deadlocks are not written into sql server errorlog, to do so we have to enable a
trace flag.

Trace Flag 1204 SQL Server 2000 or below

Trace Flag 1222 SQL Server 2005 or above

Syntax: DBCC TRACEON (1222, -1)

Note: -1 indicates trace should run for all sessions

Using the profiler:


We need to capture the Lock Events Lock: Deadlock and Lock: Deadlock Chain along with
the ObjectID data column

To prevent Deadlocks:

While updating have the application access server objects in the same order each time.
During transactions, dont allow any user input. Collect it before the transaction begins.

Keep transactions as short as possible. To accomplish this when your application does
need to read the same data more than once, cache it by storing it in a variable or an array,
and then re-reading it from there, not from SQL Server.

Reduce lock time. Develop your application to grab locks at the latest possible time, and
then releases them at the very earliest time.

If appropriate, reduce lock escalation by using the ROWLOCK or PAGLOCK.

Consider using the NOLOCK hint to prevent locking if the data being locked is not modified
often.

If appropriate, use low level isolation level according to the possibilities

77

Look for other opportunities to improve the efficiency of the queries

If both deadlock participants are using the same index, consider adding an index that can
provide an alternate access path to one of the spids.

**************************************************************************************************

Microsoft SQL Server DBA Course content (Syllabus)


Module 1: Introduction to SQL Server

Type and Shifts DBAs

Roles and Responsibilities of DBA

78

History of SQL Server & Code name

New features of SQL Server 2005 & 2008

Different Editions of SQL Server

Tools of SQL Server

Hardware and Software Requirements

Instances
Default Instance
Named Instances

SQL Server Services


Instance Aware Services
Instance Unaware Services

Module 2: Installation and configuring SQL Server


Installing SQL Server 2005 & 2008.
Pre installation steps
Installations
Viewing installation process with LOG files
Common issues.
Adding /Removing components
Installing service packs.
Best Practices after Installing SQL Server
Configuration
Configuring various Services with Local and Domain Account
Startup Parameter
Configuring data file and log file paths
Memory configuration
Remote connections
Configuring Network protocols, Ports

Module 3: Working with Databases


Working with databases.
System Defined databases
Steps to move System databases
Handling TempDb issues.

79

Database Architecture.
Data File & Log File
Filegroups
Extents
Pages types
Page architecture
Tracking free space
Log file full How to solve the problem
Creating Databases
Database Snapshots
Adding files, file groups and Schema

Module 4: Implementing Security


Security in SQL Server 2008
Types of Authentications.
Windows Authentication
Creating logins from windows users and groups
Orphan logins.
SQL Server Authentication
Creating SQL logins and testing logins
Setting authentication Mode
Security Auditing
Understanding server roles
Working with users
Resolving orphan users issues
Understanding database roles, custom and application roles
Understanding permissions
Encryption and decryption
Major issues

80

Module 5: Backup and Restoration


Understanding Transaction process
Understanding Transaction Log file
Checkpoint & Lazy writer process
Truncating log file.
Database Recovery Models
Full
Bulk Logged
Simple
Setting recovery model
Database Backups
Backup Types.
Full
Differential
Transaction Log
File or Filegroup
Copy-only, Mirrored and tail log backup
Performing Restoration operations
Practical Scenario :
Steps to Restore Master database when Server crashes.
How to Recover Database from Suspect mode.
How to Recover Database when Log file is Corrupted.

Module 6: High Availability


Introduction to High Availability

81

Working with Log Shipping


Log Shipping Requirement
Configuring Log Shipping
Monitoring Log Shipping Status
Manually performing Fail Over
Transferring logins
Log shipping tables and stored procedures
Fixing log shipping issues
Working with Database Mirroring
Difference bet Logshipping and Mirroring
Operating Modes in Mirroring
Server Roles in Mirroring
Requirements for Mirroring
Configuring Mirroring
Performing failover in Mirroring
Different Ways to monitor Mirroring Status
Mirroring system tables and stored procedures.
Major issues with mirroring.

Module 7: Replication
Replication and advantages
Replication Entities
Replication Architecture
Replication Agents
Types of Replications
Configuring Replication
Snapshot Replication
Transactional Replication
Merge Replication
Peer to peer replication
Replication Topologies

Module 8: Automating Administrative Tasks


Working with Database Mail.

82

Mail architecture.
Configuring Profiles and Accounts
Creating Operators
Sending Mail
Configuring linked servers
Implementing Automation
Configuring SQL Server Agent
Creating Jobs
Managing jobs and resolving errors.
Monitoring jobs.
Auto alert when jobs are enabled, disabled or failed.
Managing replication.
Monitoring and Tuning Replication

Module 9: Advanced Administration Concepts


Maintenance plans
Monitoring and Tuning SQL Server
Performance counters setup
Measuring performance of server.
Tuning queries.
Tuning databases.
Tuning physical architecture of databases.
Using DTA.
Monitoring Tools
Performance Monitor
SQL Server Profiler
Database Engine Tuning Advisor.
Dynamic Management Views.
SQL Server and Windows Event Logs.
Troubleshooting
Physical server performance.
Connectivity to SQL Server
Database Performance.
Using the DAC.
Shrink Files
Using DBCC commands.

83

Module 09: SQL Server Architecture

SQL Server Architecture


Relational Engine
Storage Engine
Buffer pool
Managing execution plans.

Locking and Blocking


Locks
Deadlocks
Understanding Blocking.
Terminating Processes
Transaction Isolation Levels.

Module 10: Index Management

Why Indexes

Type of Indexes
Cluster Index
Noncluster Index
Full Text Index

Creating Indexes

Manage Index Fragmentation


DBCC Showcontig
DM.DB_Index_Physical_Stats
Index Rebuilding and Reorganizing.

Manage Statistics

Performing database integrity checks

Module 11: SQL Server 2000/2005 to 2008 Upgrade Process


SSUA Tool
Upgrade Type
o Inplace Upgrade
o Side By Side Upgrade
Compatibility level
Transferring logins
Transferring Jobs

84

DTS to SSIS Migration

Module 12: Clustering


Why Clustering?
Overview of Windows Clustering.
Types of Cluster
Pre- Requisites to implement Cluster
Installing SQL Server Failover Cluster
Applying service packs and hot fixes
Performing failover
Adding node on a SQL Server Failover cluster.
Troubleshooting cluster issues

Module 13: SQL Server 2008 New Featured


Central Management Server
Data Collector
Auditing
Resource Governor
Backup Compression
******************************************************************************************
http://www.apex-online-it-training.com/Courses/microsoft-sql-server-dba-online-training-by-real-time-trainer-job-orientedsupport-at-best-and-top-institute.php

Das könnte Ihnen auch gefallen