Adsense_01

Saturday, 22 January 2011

SQL Server Memory Issue

Every one running SQL Server has always had the same issue of memory. Whatever the extra memory is given to windows, it is all eaten by the SQL Server alone. No matter what the process is going on, the memory takes much resources for all related to SQL Server. How can we control the memory issue. Well there are some possibilities from SQL Server that we can restrict the server to occupy the server memory.

--To check for the existing memory usage
use master
EXEC sp_configure 'max server memory (MB)'

By default the server won't display the advance options to enable this service. So follow the steps below to view the memory usage.

--To display advance option
USE master
EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE

After this you can run the below query to see the usage.

use master
EXEC sp_configure 'max server memory (MB)'

Then use this to change the server memory.

--To change the maximum server memory
USE master
EXEC sp_configure 'max server memory (MB)', 6144
RECONFIGURE WITH OVERRIDE

Then again you can check the usage using the query which we have see earlier. Once you are happy then you need to switch off the advanced options. And for this use the following.

--not to display advance option
USE master
EXEC sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE

Give a try!

Friday, 21 January 2011

Add a new column to every table in a database

This seems quite a painful job when so many start opening a table and add the new column name, datatype and save. But what about you have to do this for 200 tables in a database and say you have 10 databases. Hmmm.... Such a crap work doing manually but SQL Server infamiliar stored procedure comes to rescue at this point.

The below query can be used to add a new column to every single table in a database.

Use [db]
go
exec sp_MsForEachTable 'alter table ? add Load_date datetime null'


Thats it. You are done. Change the database name for the other databases.

So it is not just adding a column to all table, but modifying anything similar for each table in a database. You can change the SQL statement within the single quotes.

Best of luck.

Thursday, 20 January 2011

Template explorer and Parameters

To view the template explorer click View => Template explorer.

Drag and drop any template to create a table, view or stored procedure into a new query editor window. Then click on the main menu option Query => Specify Values for Template Parameters option to specify schema name, procedure name, values for any parameters, etc.,


These values will be applied to every single place in the template query. Then the new table, view ore stored procedures can be created according to your needs.

Wednesday, 19 January 2011

SQL Server Editions

SQL Server comes in 2 Editions with different versions. They are categorized below.

1. Server Editions
  • Enterprise (32bit, 64bit & IA64)
  • Standard (32bit, 64bit)
  • Standard for Small Business

2. Specialized EditionsDeveloper (32bit, 64bit & IA64)
  • Workgroup (32bit, 64bit)
  • Web (32bit, 64bit)
  • Express (32bit, 64bit)
  • Express with Advanced Services (32bit, 64bit)
  • Compact (32bit)

Tuesday, 18 January 2011

Microsoft Certified Master - SQL Server

This blog is started with the intention of helping everyone who wants to shine in SQL Server arena. As an individual I prepare for my Microsoft Certified Masters in SQL Server and share my readings, researches, and other useful information here.

Wish you all the very best in your findings.

Sunday, 4 July 2010

Memory upgrade can lead to performance issues

I had a live scenario where my servers were upgraded with the memory and all my ETL & Replication were totally down. Couldn't figure out the actual issue and need to reset the whole process and run manually. I have about 6TB of database and 4Bn records. My initial workout with the admin guy is to find out the server problem itself and then came out with the server is kind of parallelized with the faulty motherboard. I have 2 processor and equal amount of RAM supplied to both of them. When the memory was upgraded equally one part of the processor couldn't recognize the memory and found the faulty motherboard. One side it was good to find out the actual memory in place helped to identify and replace the faulty one. But on the other side the production system was totally disastrous. Then need to configure with the resource governor to distinguish the workload to help more for replication and also the default one. After the resource governor was setup properly, the following query produced the results to show average time take per millisecond.

SELECT
             rpool.name as PoolName,
             COALESCE(SUM(rgroup.total_request_count), 0)as TotalRequest,
             COALESCE(SUM(rgroup.total_cpu_usage_ms), 0)as TotalCPUinMS,
             CASE
                   WHEN SUM(rgroup.total_request_count) > 0 THEN
                         SUM(rgroup.total_cpu_usage_ms) /SUM(rgroup.total_request_count)
                         ELSE
                         0
                  END as AvgCPUinMS
FROM       sys.dm_resource_governor_resource_pools AS rpool LEFT OUTER JOIN
        sys.dm_resource_governor_workload_groups AS rgroup
        ON rpool.pool_id = rgroup.pool_id
GROUP BY  rpool.name
GO

Result:

PoolName             TotalRequest              TotalCPUinMS              AvgCPUinMS
--------------------------------------------------------------------------------
PP_BusUsers                           0                           0                                        0
PP_SSUsers                           0                           0                                        0
distribution              2613809                           30510900                           11
default                     5730860                           179191854                           31
internal                                     0                           4966873                           0

Thursday, 15 April 2010

Resource Governor for all users in a group

It was a hard part initially to make use of balancing the resources for all users with different groups. We can make use of IS_MEMBER() function, but the Function Classifier need to be derived accordingly. Also this is not an 100% workout to get the ideal result. I have recently come out with good work around to sort out this issue.

To give a scenario, I have 3 sets of SQL users. Moreover I also have replication stuff going on.
1. Business Team with developers knowledge
2. Business team with basic knowledge + pivot table manipulators in excel
3. IT team

I need to balance the users login on one side & the replication on the other.

I have used 3 Workload groups & Resouce pools on top of the server's default & internal pools.

--**CREATE RESOURCE POOL **--
CREATE RESOURCE POOL SSUsers
WITH (MAX_CPU_PERCENT = 2, MAX_MEMORY_PERCENT = 2);
go

CREATE RESOURCE POOL DevUsers
WITH (MAX_CPU_PERCENT = 4, MAX_MEMORY_PERCENT = 4);
go

CREATE RESOURCE POOL Distribution
WITH (MIN_CPU_PERCENT = 15, MAX_CPU_PERCENT = 40, MIN_MEMORY_PERCENT = 40, MAX_MEMORY_PERCENT = 60);
go

--to reconfigure the created resource pools, i used the following
ALTER RESOURCE GOVERNOR RECONFIGURE;
go

--the below query displays the newly created resource pools with its ID.
SELECT * FROM sys.dm_resource_governor_resource_pools;
go

--**CREATE WORKLOAD GROUP **--
--create workload group to assign to the resource pools

CREATE WORKLOAD GROUP WG_SSUsers
USING SSUsers;
go

CREATE WORKLOAD GROUP WG_DevUsers
USING DevUsers;
go

CREATE WORKLOAD GROUP WG_Distribution
USING distribution;
GO

--to reconfigure the created resource pools, i used the following
ALTER RESOURCE GOVERNOR RECONFIGURE;
GO

--the below query displays the newly created workload groups with its ID.
SELECT * FROM sys.dm_resource_governor_workload_groups


I am going to write a classifier function that will distinguish the users and the replication database and allocated the workload groups accordingly.

Before creating the classifier function I need to have all the list of users underneath their group level. In our case, I had issue in using IS_MEMBER() function where it was able to allocate resource for the first set of rules defined in the classifier function. Then I came out with adding the list of user to a physical table with their permissions level in the master database. You can execute the following against your master database.

Use master
go

CREATE TABLE RG_Users_Group
(
RG_Name NVARCHAR(15) NULL,
Username NVARCHAR(25) NULL

)

INSERT INTO rg_users_group VALUES ('SS_Users', 'AB01\user1')
INSERT INTO rg_users_group VALUES ('SS_Users',  'AB01\user2')
INSERT INTO rg_users_group VALUES ('SS_Users',  'AB01\user3')
INSERT INTO rg_users_group VALUES ('SS_Users',  'AB01\user4')
INSERT INTO rg_users_group VALUES ('Dev_Users',  'AB01\user5')
INSERT INTO rg_users_group VALUES ('Dev_Users',  'AB01\user6')


This creates a list of all users with proper Resource Group name. The output of the table looks like this.

RG_Name                       Username
------------------------------
SS_Users                         AB01\user1
SS_Users                        AB01\user2
SS_Users                        AB01\user3
SS_Users                        AB01\user4
Dev_Users                    AB01\user5
Dev_Users                    AB01\user6

Once the table is created then I write my classifier function here.
--create the classifier function to assign the workload groups
IF OBJECT_ID ( 'dbo.RGov_Classifier') IS NOT NULL
 DROP FUNCTION dbo.RGov_Classifier;
go
CREATE FUNCTION dbo.RGov_Classifier ()
RETURNS sysname WITH SCHEMABINDING
AS
BEGIN
 RETURN
 (
  SELECT CASE WHEN SUSER_NAME() IN (SELECT username FROM dbo.rg_users_group WHERE RG_name = 'SS_Users')
      THEN N'WG_SSUsers'
     WHEN SUSER_NAME() IN (SELECT username FROM dbo.rg_users_group WHERE RG_name = 'Dev_Users')
      THEN N'WG_DevUsers'
     WHEN ORIGINAL_DB_NAME () = 'distribution'
      THEN N'WG_Distribution'
    ELSE N'default'
    END
 );
END;
go

--register the classifier function to the RG.
ALTER RESOURCE GOVERNOR
 WITH (CLASSIFIER_FUNCTION = dbo.RGov_Classifier);
GO
ALTER RESOURCE GOVERNOR RECONFIGURE;
GO

Now the creation of all resource pools, workload groups, table & classifier function is done. It is time to check how the resource group works. So I have the following query to check each resource pools & their average response in milliseconds.

USE MASTER;
GO
SELECT
             RP.name as PoolName,
             COALESCE(SUM(RG.total_request_count), 0)as Total_Request,
             COALESCE(SUM(RG.total_cpu_usage_ms), 0)as Total_CPU_in_MS,
             CASE
                   WHEN SUM(RG.total_request_count) > 0 THEN
                         SUM(RG.total_cpu_usage_ms) /SUM(RG.total_request_count)
                         ELSE
                         0
                  END as Avg_CPU_in_MS
       FROM
       sys.dm_resource_governor_resource_pools AS RP
       LEFT OUTER JOIN
       sys.dm_resource_governor_workload_groups AS RG
       ON
           RP.pool_id = RG.pool_id
       GROUP BY
           RP.name;

In the above query, I have used the DMV (Dynamic Management Views) to help in identifying the resources used for each pool.

PoolName         Total_Request                Total_CPU_in_MS      Avg_CPU_in_MS
DevUsers             3644                                       13412519                              3680
SSUsers                50                                           243846                                  4876
distribution        1340523                                16428325                             12
default                  621057                                  822676774                           1324
internal                0                                             3182271                                0

In the above scenario, I made sure all the resource pool now works fine.

This is not an 100% solution, and still have some work around to better up the results. But still a good work around compared to the other scenario.

Let me know if you need any clarifications on this.