Showing posts with label Performance. Show all posts
Showing posts with label Performance. Show all posts

Tuesday, May 2, 2017

Use of functions on indexed columns in predicates

Use of functions on indexed columns which are used in predicates results in index not getting used for seek operation.

For example:

Use tempdb
set nocount on
go

IF OBJECT_ID(N'Customers', N'U') IS NOT NULL
   DROP TABLE dbo.Customers;
  
CREATE TABLE dbo.Customers (
 customer_nbr INT NOT NULL PRIMARY KEY,
 customer_name VARCHAR(35) NOT NULL);

CREATE NONCLUSTERED INDEX ix_customers
ON dbo.Customers(customer_name);

INSERT dbo.Customers VALUES(1, 'Joe');
INSERT dbo.Customers VALUES(2, 'Leo');
INSERT dbo.Customers VALUES(3, 'Dave');
INSERT dbo.Customers VALUES(4, 'Lenny');
INSERT dbo.Customers VALUES(5, 'Larry');
INSERT dbo.Customers VALUES(6, 'Lefty');
INSERT dbo.Customers VALUES(7, 'Lemur');

GO

If I want to write a query on this table to get all the customers whose first name starts with 'L'.
SELECT customer_name
FROM dbo.Customers
WHERE LEFT(customer_name, 1) = 'L';

Looking at the execution plan for above query. We can see index scan in here and not seek:










Now, what if we rewrite this query without the use of LEFT function as below:
SELECT customer_name
FROM dbo.Customers
WHERE customer_name LIKE 'L%';

Looking at the execution plan for above query shows us index seek and the output of query is same as before.










Functions on indexed column used in predicates makes them non-sargable and impacts performance.



Reference:
https://sqlbits.com/Sessions/Event14/Common_TSQL_Mistakes









Thursday, May 24, 2012

How to Partition a Table in SQL Server..

What is Table Partitioning?
Table partitioning is built-in method of horizontally  partitioning data within a table and/or index still maintaining the table as a single logical object.  Partitioning keeps the same no of columns in each partition, but reducing the number of rows.

Why do we need Table Partitioning?

- Easy management of large tables and indexes.
- Decrease load time.
- Improve query performance.
- Provide small window for maintenance, means easy to maintain chunks of data instead of whole.

How Partitioning is done?

- Create file -groups to hold the partitions.
- Add files to each file -group in the partitioning.
- Create Partition Function.
- Create Partition Scheme.
- Create table , binding  a specific column to a  Partition Scheme.

Below is an example of partitioning a table:

Create a sample database to be used for partitioning. I have added two file groups other than the primary file group to it.
CREATE DATABASE [PartitionDB] ON
PRIMARY
      (     NAME = N'PartitionDB',
            FILENAME = N'C:\PartitionDB\PartitionDB.mdf' ,
            SIZE = 3072KB , FILEGROWTH = 1024KB
      ),
FILEGROUP [FG2]
      (     NAME = N'PartitionDB_2',
            FILENAME = N'C:\PartitionDB\PartitionDB_2.ndf' ,
            SIZE = 3072KB , FILEGROWTH = 1024KB
      )
FILEGROUP [FG3]
      (     NAME = N'PartitionDB_3',
            FILENAME = N'C:\PartitionDB\PartitionDB_3.ndf' ,
            SIZE = 3072KB , FILEGROWTH = 1024KB
      )
LOG ON
      (     NAME = N'PartitionDB_log',
            FILENAME = N'C:\PartitionDB\PartitionDB_log.ldf' ,
            SIZE = 9216KB , FILEGROWTH = 10%
      )
Now we create a Partition Function. Partition Function can be used for any Partition Scheme. Please read the below link for specific details about the partition function:
CREATE PARTITION FUNCTION EqualFunc (INT)
AS RANGE LEFT
FOR VALUES (0,1)
Next step is to create a Partition Scheme. Here is the link for Partition Scheme:
CREATE PARTITION SCHEME EqualScheme
AS PARTITION EqualFunc
TO (FG2, FG3, [PRIMARY])


Finally we create a table using the Partition Scheme that we created. Based on the value of ID column PartitionElement will be computed and that will be used in deciding on which file group the row will be stored.


CREATE TABLE Customer
(
      ID     INT,
      Name        VARCHAR(20),
      PartitionElement AS ID % 3 PERSISTED
)
ON EqualScheme (PartitionElement)

INSERT INTO Customer(ID,Name) VALUES(3,'abc3')
INSERT INTO Customer(ID,Name) VALUES(1,'abc1')
INSERT INTO Customer(ID,Name) VALUES(2,'abc2')
Below query will determine the rows in each partition that is created for the table.
SELECT partition_id, object_id, partition_number, rows
FROM sys.partitions
WHERE object_id = OBJECT_ID('Customer')
If we want to get the resultset for the particular partition here is the query
SELECT *
FROM  Customer
WHERE $PARTITION.EqualFunc(PartitionElement) = 2



It is advisable to keep the filegroups on different disk drives for parallelism. Partitioning is a great way to improve performance for the tables with large amount of data.

Saturday, May 5, 2012

Memory Behavior in SQL Server

Memory behavior of SQL Server 2008 is very different from SQL Server 2005. On observing the memory utilization of the server on which SQL Server was installed we found that SQL Server takes up all the memory that is available. But we were not completely right. By doing some research I came up with below summary:





o   “When you start SQL Server, SQL Server memory usage may continue to steadily increase and not decrease, even when activity on the server is low. Additionally, the Task Manager and Performance Monitor may show that the physical memory available on the computer is steadily decreasing until the available memory is between 4 to 10 MB.This behavior alone does not indicate a memory leak. This behavior is normal and is an intended behavior of the SQL Server buffer pool.”
o   “By default, SQL Server dynamically grows and shrinks the size of its buffer pool (cache) depending on the physical memory load reported by the operating system. As long as enough memory is available to prevent paging (between 4 - 10 MB), the SQL Server buffer pool will continue to grow. As other processes on the same computer as SQL Server allocate memory, the SQL Server buffer manager will release memory as needed. SQL Server can free and acquire several megabytes of memory each second, allowing it to quickly adjust to memory allocation changes.”
o   You can establish upper and lower limits to the amount of memory (buffer pool) used by the SQL Server database engine with the min server memory and max server memory configuration options.
o   “Note that the max server memory option only limits the size of the SQL Server buffer pool. The max server memory option does not limit a remaining unreserved memory area that SQL Server leaves for allocations of other components such as extended stored procedures, COM objects, non-shared DLLs, EXEs, and MAPI components. Because of the preceding allocations, it is normal for the SQL Server private bytes to exceed themax server memory configuration. ”
o   If you are running 32-bit SQL Server, and need access to more than 2 GB of user mode VAS (Virtual Address Space), then you have to use Lock Pages in Memory; there is no debate there. You must configure the OS to use Physical Address Extensions (PAE), enable Address Windowing Extensions (AWE), and then assign the Lock Pages in Memory permission to the SQL Server account so that it can allocate AWE memory, via calls to AllocateUserPhysicalPages() (Windows API). So, in a typical 32-bit server using LPIM(Lock Pages In Memory) you'd have, in addition to the 2 GB of pageable user mode VAS, a separate AWE-mapped area, up to 64 GB (the PAE pointer was 36-bit), of non-pageable memory. This AWE-mapped area is for exclusive use by the data cache portion of the buffer pool. The rest of the buffer pool (mainly the plan cache), and other non-buffer pool allocations are still mapped within the 2 GB of user mode VAS.
o   However, the advent of a 64-bit SQL Server process completely changed the dynamics of memory allocation by the SQLOS. In place of the default 2 GB user mode VAS, for a 32-bit process, a 64-bit process has access to up to 8 TB of user mode VAS out-of-the-box, without any need for further configuration changes! 64-bit users now have a potentially-vast amount of memory for the buffer pool, but all of which is allocated via VirtualAlloc, and backed by user mode VAS, and so is pageable i.e. in the absence of LPIM, the memory allocated for the data and plan cache is pageable.
o   Since the operating system still requires memory to operate, you should set the max server memory configuration option to ensure that the operating system has sufficient memory once SQL Server has committed its memory for use.  This is especially important on 64 bit servers where the larger VAS allows for the SQL process to take all of the physical memory which can result in a paging situation for the SQL processes, degrading performance.  For this reason, 64 bit servers should use the Lock Pages in Memory right so that the AWE Mechanism is used to allocate memory, preventing paging of the BPool. 


References:

TempDB Configuration in SQL Server

Recently in our production environment we were facing performance issues. After tracking down we found that reason could be because of incorrect tempDB configuration. So, I started reading few articles on msdn and written by experts about tempDB configuration and came up with below summary.


·         Should I use 1 file or multiple files for TempDB?
o   One TempDB data file per physical corefor the SQL Server instance.This prevents helps contention that can occur during peak tempdb activity.
o   The data files for tempdb should all be the same size. This allows for optimal proportional-fill performance.
o   All data files have equal growth increment
o   No data files have percent growth increment
·         Where (i.e. what disks) should I create TempDB?
o   Put the tempdb database on a fast I/O subsystem. Use disk striping if there are many directly attached disks.
o   Put the tempdb database on disks that differ from those that are used by user databases.Tempdb should be separated and isolated from user databases.  This creates contention between the user databases and tempdb.
o   Tempdb data files and log files should be on separate disks.
o   The TempDB files should definitely not be on the system (C) drive. If TempDB grows out of control, perhaps due to a large sort query, the system can run out of hard drive space and fail to start.
·         What should be the size of TempDB?
o   Unlike user databases where you can probably estimate the growth rate of tables over time based on the workload, estimating the size of TempDB is non-trivial.
o   The size of TempDB can be affected for example by a change in query plans, version store when there is a long running transaction and so on.
o   The best way to estimate the size of TempDB is by running your workload in a test environment. Once you have a good estimate of the size of TempDB, use Alter Database command to set its size with a safety factor that you feel is appropriate.
o   Don’t rely on auto-grow to manage file sizes. You must set the appropriate size of TempDB using Alter Database command.
o    Auto-grow causes a pause during processing when you can least afford it
o   Auto-grow leads to physical fragmentation
o   Tempdb Data files should be large enough to handle the workload for all 24 hours of the day.