Using functions for calculations

Posted by Jeff Rix on June 29, 2011 under DBA | Be the First to Comment

I need to calculate the detention attendance rate. In order to do this I need to get a count of detentions closed and a count of detentions attended.

 –Determines Percentage of Students that have attended
  SELECT A.DETENTION_DATE,
 
 
CAST(CAST(A.COUNT_CLOSED AS DECIMAL(4,2))/ CAST(B.COUNT_TOTAL AS DECIMAL(4,2)) AS DECIMAL(4,2)) as Percentage

 
FROM
   
–Gets Closed count by Detention Date
  (

 
select DETENTION_DATE, STATUS, COUNT(*) as Count_Closed
 
from Discipline.dbo.DETENTION_DATE
 
where status = ‘Closed’
 
group by DETENTION_DATE, status

 
) as a
 
join 
  
–Gets Total count by Detention Date
  (

 
select DETENTION_DATE, COUNT(*) as Count_Total
 
from Discipline.dbo.DETENTION_DATE
 
group by DETENTION_DATE
 
) as  b on a.DETENTION_DATE = b.DETENTION_DATE
 
If I put this into a function and then call the function I will get a lower cost way to calculate detention attendance rates.
 
Here is the code to put the select statement into a function.
CREATE FUNCTION [dbo].[CalcAttendancePercent]
(@DetentionDate Datetime) Returns DECIMAL(4,2)
AS
 
BEGIN
  
DECLARE @Percentage as DECIMAL(4,2)   
 
SELECT @Percentage = CAST(A.COUNT_CLOSED AS DECIMAL(4,2))/ CAST(B.COUNT_TOTAL AS DECIMAL(4,2))

 
FROM
 
(
 
select DETENTION_DATE, STATUS, COUNT(*) as Count_Closed
 
from Discipline.dbo.DETENTION_DATE
 
where status = ‘Closed’ AND DETENTION_DATE = @DetentionDate
 
group by DETENTION_DATE, status
 
) as a
 
join 
 
(

 
select DETENTION_DATE, COUNT(*) as Count_Total
 
from Discipline.dbo.DETENTION_DATE
 
where DETENTION_DATE = @DetentionDate
 
group by DETENTION_DATE
 
) as  b on a.DETENTION_DATE = b.DETENTION_DATE
 
RETURN @Percentage
END
 
Here is the code to call the function.
 
  –using a function to calculate the percentage
SELECT DETENTION_DATE, dbo.CalcAttendancePercent(DETENTION_DATE) as Percentage

FROM Discipline.dbo.DETENTION_DATE
GROUP BY DETENTION_DATE
 
The code that calls the function has a lower cost than using the original sql statement.

image

Finding fragmented indexes and rebuilding indexes

Posted by Jeff Rix on April 28, 2011 under DBA | Be the First to Comment

Find Indexes to Rebuild-find indexes with a page count greater than ten thousand and fragmentation above ninety percent.

 

SELECT ps.database_id, c.name as table_name, ps.OBJECT_ID,

ps.index_id, b.name, ps.avg_fragmentation_in_percent, ps.page_count

FROM sys.dm_db_index_physical_stats (DB_ID(), NULL, NULL, NULL, NULL) AS ps

INNER JOIN sys.indexes AS b ON ps.OBJECT_ID = b.OBJECT_ID

INNER JOIN sys.all_objects as c on ps.object_id = C.object_id

AND ps.index_id = b.index_id where ps.avg_fragmentation_in_percent > 90 and ps.page_count > 10000

ORDER BY ps.avg_fragmentation_in_percent desc

 

 

Before Index is Rebuilt- fragmentation is caused by data modification and can cause leaf pages to be out of order and index pages to not be used to their maximum value.

 

–turn statistics on to get logical reads

SET STATISTICS IO ON

 

–select columns form the composite primary key (clustered index).

SELECT DISTRICT, SECTION_KEY, COURSE_SESSION, STUDENT_ID, ASMT_NUMBER FROM Student_ASMT_Grade

 

Fragmentation at ninety eight percent

 

Logical reads 141,182

Page count: 86,684

Estimated IO Cost 103.782

Estimated Operator Cost 107.59

 

Code to Rebuild Index

 

USE [YESPrep_DW]

GO

ALTER INDEX [PK_Student_ASMT_Grade] ON [dbo].[Student_ASMT_Grade] REBUILD PARTITION = ALL WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, ONLINE = OFF, SORT_IN_TEMPDB = OFF )

GO

 

After Index is Rebuilt- rebuilding indexes cuts logical reads in half because index is no longer fragmented. Custs Cost in half.

 

SET STATISTICS IO ON

 

SELECT DISTRICT, SECTION_KEY, COURSE_SESSION, STUDENT_ID, ASMT_NUMBER FROM Student_ASMT_Grade

 

Logical reads 86,998

Page count: 86,684

Estimated IO Cost 64.2128

Estimated Operator Cost 68.2128

 

Fragmentation is now at zero percent