Database
Data Warehouse Design Approaches
Written by Harry Zheng   
  • Top down

Data Warehouse -> Data Mart 1, 2, 3 ...

Recommended by Bill Inmon. Transfer all OLTP data to data warehouse. Data marts are sub sets of DW. 

Data flow:

OLTP data -> Staging -> Operational Data Store (ODS) -> Aggregation, Summarization -> Data Warehouse -> Staging -> Transformation -> Data Marts

OLTP data -> Staging -> Data Warehouse (atomic level)

  • Bottom Up

Data Mart 1 - Data Mart 2 - Data Mart 3 - ...

Recommended by Ralph Kimball. Data Marts connected with a bus structure to form a data warehouse.

Data Flow:

OLTP data -> Staging -> Operational Data Store (ODS) -> Data Mart -> Staging -> Aggregation, Summarization -> Data Warehouse

  • Hybrid

Data Flow:

OLTP data -> Staging  -> Aggregation, Summarization -> Data Mart (contains both atomic and summary data) -> Staging -> Data Warehouse

Query tools are reprogrammed to request summary data from the marts and atomic data from the data warehouse.

  • Federated

Hub-and-spoke architecture

Integration of heterogeneous data warehouses, data marts that already exist in the enterprise. 

 

Last Updated on Sunday, 20 June 2010 15:43
 
How to perform an unattended upgrade of SQL Server 2008 R2
Written by Harry Zheng   
  1. Run setup.exe from a network location (installation directory).

  2. Follow the wizard through to the Ready to Upgrade page. The path to the configuration file is specified in the Read to Upgrade page in the configuration file path section.

  3. Cancel the setup without actually completing the installation, to generate the INI file.

  4. Copy the ConfigurationFile.ini to the same folder of the installation directory.

  5. Create a new file on the installation directory and name it upgrade.bat

  6. Open upgrade.bat with Notepad and add the follow line: Setup.exe /ConfigurationFile=ConfigurationFile.ini

  7. Open ConfigurationFile.ini with Notepad 

    1. Add this line to the beginning of the file after [SQLSERVER2008]: IAcceptSQLServerLicenseTerms="True"

    2. Change QUIETSIMPLE="False" to QUIETSIMPLE="True"

    3. Comment out this line: UIMODE="Normal" ->  ;UIMODE="Normal"

  8. Save all files.

  9. Double click on upgrade.bat will launch the upgrade process.

Reference: 

  1. http://msdn.microsoft.com/en-us/library/dd239405.aspx
  2. http://msdn.microsoft.com/en-us/library/ms144259.aspx
Last Updated on Saturday, 19 June 2010 12:06
 
SQL Server 2008 Performance Tuning with DMVs
Written by Harry Zheng   

Select '1. CPU Bottlenecks'

--Top queries that useed up most of the CPUs
select top 50
    sum(qs.total_worker_time) as total_cpu_time,
    sum(qs.execution_count) as total_execution_count,
    count(*) as  number_of_statements,
    qs.plan_handle
from
    sys.dm_exec_query_stats qs
group by qs.plan_handle
order by sum(qs.total_worker_time) desc

Select '1.1 Excessive Query Compilation and Optimization'
Select 'Identify ad hoc queries and candidate for parameterizing?'
select q.query_hash,
 q.number_of_entries,
 t.text as sample_query,
 p.query_plan as sample_plan
from (select top 20 query_hash,
   count(*) as number_of_entries,
   min(sql_handle) as sample_sql_handle,
   min(plan_handle) as sample_plan_handle
  from sys.dm_exec_query_stats
  group by query_hash
  having count(*) > 1
  order by count(*) desc) as q
 cross apply sys.dm_exec_sql_text(q.sample_sql_handle) as t
 cross apply sys.dm_exec_query_plan(q.sample_plan_handle) as p

select 'This query returns a count of the number of distinct query plans for a given query_hash value'
select q.query_hash,
 q.number_of_entries,
 q.distinct_plans,
 t.text as sample_query,
 p.query_plan as sample_plan
from (select top 20 query_hash,
   count(*) as number_of_entries,
   count(distinct query_plan_hash) as distinct_plans,
   min(sql_handle) as sample_sql_handle,
   min(plan_handle) as sample_plan_handle
  from sys.dm_exec_query_stats
  group by query_hash
  having count(*) > 1
  order by count(*) desc) as q
 cross apply sys.dm_exec_sql_text(q.sample_sql_handle) as t
 cross apply sys.dm_exec_query_plan(q.sample_plan_handle) as p
go

--ALTER DATABASE AdventureWorks SET PARAMETERIZATION FORCED

select '1.2 Unnecessary Recompilation'
--Take two snapshots of this DMV to see how much time is spent optimizing in the given time period.
select * from sys.dm_exec_query_optimizer_info

select top 25
    sql_text.text,
    sql_handle,
    plan_generation_num,
    execution_count,
    dbid,
    objectid
from
    sys.dm_exec_query_stats a
    cross apply sys.dm_exec_sql_text(sql_handle) as sql_text
where
    plan_generation_num >1
order by plan_generation_num desc

select '1.3 Inefficient Query Plan'
select
    highest_cpu_queries.plan_handle,
    highest_cpu_queries.total_worker_time,
    q.dbid,
    q.objectid,
    q.number,
    q.encrypted,
    q.[text]
from
    (select top 20
        qs.plan_handle,
        qs.total_worker_time
    from
        sys.dm_exec_query_stats qs
    order by qs.total_worker_time desc) as highest_cpu_queries
    cross apply sys.dm_exec_sql_text(plan_handle) as q
order by highest_cpu_queries.total_worker_time desc

 

Select *
from sys.dm_exec_cached_plans
cross apply sys.dm_exec_sql_text(plan_handle)
where dbid = db_id('SFSLearner')


Select *
from sys.dm_exec_cached_plans
cross apply sys.dm_exec_sql_text(plan_handle)
where dbid = db_id()


Select 'Consider plan freeze'
--DECLARE @plan_handle varbinary(64);

---- Extract the query's plan_handle.
--SELECT @plan_handle = plan_handle FROM sys.dm_exec_query_stats AS qs
--CROSS APPLY sys.dm_exec_sql_text(sql_handle)
--WHERE text LIKE N'Some query matching criteria%';

--EXECUTE sp_create_plan_guide_from_handle
--    @name =  N'Sample_PG1',
--    @plan_handle = @plan_handle,
--    @statement_start_offset = NULL;
--GO


select '1.4 Intraquery Parallelism'
Select 'Determine whether any active requests are running in parallel for a given session'
select
    r.session_id,
    r.request_id,
    max(isnull(exec_context_id, 0)) as number_of_workers,
    r.sql_handle,
    r.statement_start_offset,
    r.statement_end_offset,
    r.plan_handle
from
    sys.dm_exec_requests r
    join sys.dm_os_tasks t on r.session_id = t.session_id
    join sys.dm_exec_sessions s on r.session_id = s.session_id
where
    s.is_user_process = 0x1
group by
    r.session_id, r.request_id,
    r.sql_handle, r.plan_handle,
    r.statement_start_offset, r.statement_end_offset
having max(isnull(exec_context_id, 0)) > 0


Select 'Find query plans that can run in parallel'
select
    p.*,
    q.*,
    cp.plan_handle
from
    sys.dm_exec_cached_plans cp
    cross apply sys.dm_exec_query_plan(cp.plan_handle) p
    cross apply sys.dm_exec_sql_text(cp.plan_handle) as q
where
    cp.cacheobjtype = 'Compiled Plan' and
    p.query_plan.value('declare namespace p="http://schemas.microsoft.com/sqlserver/2004/07/showplan";
        max(//p:RelOp/@Parallel)', 'float') > 0

Select 'Find parallel queries by searching all queries that use more CPU time than the elapsed duration.'
select
    qs.sql_handle,
    qs.statement_start_offset,
    qs.statement_end_offset,
    q.dbid,
    q.objectid,
    q.number,
    q.encrypted,
    q.text
from
    sys.dm_exec_query_stats qs
    cross apply sys.dm_exec_sql_text(qs.plan_handle) as q
where
    qs.total_worker_time > qs.total_elapsed_time


select '1.5 Poor Cursor Usage'
Select 'Search for API cursor'
select
    cur.*
from
    sys.dm_exec_connections con
    cross apply sys.dm_exec_cursors(con.session_id) as cur
where
    cur.fetch_buffer_size = 1 --API cursor (Transact-SQL cursors always have a fetch buffer of 1)
    and cur.properties LIKE 'API%' 


Select '2. Memory Bottlenecks'
Select '2.1 External Physical Memory Pressure'
Select 'Find out how much memory SQL Server has allocated through the AWE mechanism.'
select
    sum(awe_allocated_kb) / 1024 as [AWE allocated, Mb]
from
    sys.dm_os_memory_clerks

select
 *
From sys.dm_os_process_memory

Select 'Detect external memory pressure throu sys.dm_os_sys_memory'
select 'Look for System_Memory_State_Desc = Available physical memory is low'
select
 total_physical_memory_kb / 1024 as phys_mem_mb,
 available_physical_memory_kb / 1024 as avail_phys_mem_mb,
 system_cache_kb /1024 as sys_cache_mb,
 (kernel_paged_pool_kb + kernel_nonpaged_pool_kb) / 1024
  as kernel_pool_mb,
 total_page_file_kb / 1024 as total_page_file_mb,
 available_page_file_kb / 1024 as available_page_file_mb,
 system_memory_state_desc 
from sys.dm_os_sys_memory

Select '2.2 External Virtual Memory Pressure'

Select '2.3 Internal Physical Memory Pressure'

Select 'Check the amount of memory that is consumed through the multipage allocator.'
select sum(multi_pages_kb) from sys.dm_os_memory_clerks

Select 'If you are seeing large amounts of memory allocated through the multipage allocator, check the server configuration and try to identify the components that consume most of the memory by using the previous SELECT statement.'
select
    type, sum(multi_pages_kb) as [KB]
from
    sys.dm_os_memory_clerks
where
    multi_pages_kb != 0
group by type
order by 2 desc

Select 'Amount of memory consumed by components outside the bBuffer pool'
-- note that we exclude single_pages_kb as they come from BPool
-- BPool is accounted for by the next query
select
    sum(multi_pages_kb
        + virtual_memory_committed_kb
        + shared_memory_committed_kb) as [Overall used w/o BPool, Kb]
from
    sys.dm_os_memory_clerks
where
    type <> 'MEMORYCLERK_SQLBUFFERPOOL'

Select 'Amount of memory consumed by BPool'
-- note that currenlty only BPool uses AWE
select
    sum(multi_pages_kb
        + virtual_memory_committed_kb
        + shared_memory_committed_kb
        + awe_allocated_kb) as [Used by BPool with AWE, Kb]
from
    sys.dm_os_memory_clerks
where
    type = 'MEMORYCLERK_SQLBUFFERPOOL'


Select 'Detailed information for each component can be obtained as follows. (This includes memory allocated from both within and outside of the buffer pool.)'
Begin
 declare @total_alloc bigint
 declare @tab table (
  type nvarchar(128) collate database_default
  ,allocated bigint
  ,virtual_res bigint
  ,virtual_com bigint
  ,awe bigint
  ,shared_res bigint
  ,shared_com bigint
  ,topFive nvarchar(128)
  ,grand_total bigint
 );

 -- note that this total excludes buffer pool committed memory as because it represents the largest consumer, which is normal
 select
  @total_alloc =
   sum(single_pages_kb
    + multi_pages_kb
    + (CASE WHEN type <> 'MEMORYCLERK_SQLBUFFERPOOL'
     THEN virtual_memory_committed_kb
     ELSE 0 END)
    + shared_memory_committed_kb)
 from
  sys.dm_os_memory_clerks

 print
  'Total allocated (including from bBuffer pPool): '
  + CAST(@total_alloc as varchar(10)) + ' Kb'

 insert into @tab
 select
  type
  ,sum(single_pages_kb + multi_pages_kb) as allocated
  ,sum(virtual_memory_reserved_kb) as vertual_res
  ,sum(virtual_memory_committed_kb) as virtual_com
  ,sum(awe_allocated_kb) as awe
  ,sum(shared_memory_reserved_kb) as shared_res
  ,sum(shared_memory_committed_kb) as shared_com
  ,case  when  (
   (sum(single_pages_kb
    + multi_pages_kb
    + (CASE WHEN type <> 'MEMORYCLERK_SQLBUFFERPOOL'
     THEN virtual_memory_committed_kb
     ELSE 0 END)
    + shared_memory_committed_kb))/(@total_alloc + 0.0)) >= 0.05
     then type
     else 'Other'
  end as topFive
  ,(sum(single_pages_kb
   + multi_pages_kb
   + (CASE WHEN type <> 'MEMORYCLERK_SQLBUFFERPOOL'
    THEN virtual_memory_committed_kb
    ELSE 0 END)
   + shared_memory_committed_kb)) as grand_total
 from
  sys.dm_os_memory_clerks
 group by type
 order by (sum(single_pages_kb + multi_pages_kb + (CASE WHEN type <>
 'MEMORYCLERK_SQLBUFFERPOOL' THEN virtual_memory_committed_kb ELSE 0 END) +
 shared_memory_committed_kb)) desc

 select  * from @tab
End

Select 'Determine the top ten consumers of the buffer pool pages (via a single-page allocator)'
select
    top 10 type,
    sum(single_pages_kb) as [SPA Mem, Kb]
from
    sys.dm_os_memory_clerks
group by type
order by sum(single_pages_kb) desc


Select '2.4 Caches and Memory Pressure'
Select 'The internal clock hand controls the size of a cache relative to other caches. It starts moving when the framework predicts that the cache is about to reach its cap. '
Select 'The external clock hand starts to move when SQL Server as a whole gets into memory pressure. Movement of the external clock hand can be due external as well as internal memory pressure.'

select *
from
    sys.dm_os_memory_cache_clock_hands
where
    rounds_count > 0
    and removed_all_rounds_count > 0

Select 'Additional information about the caches'
select
    distinct cc.cache_address,
    cc.name,
    cc.type,
    cc.single_pages_kb + cc.multi_pages_kb as total_kb,
    cc.single_pages_in_use_kb + cc.multi_pages_in_use_kb as total_in_use_kb,
    cc.entries_count,
    cc.entries_in_use_count,
    ch.removed_all_rounds_count,
    ch.removed_last_round_count
from
    sys.dm_os_memory_cache_counters cc
    join sys.dm_os_memory_cache_clock_hands ch on (cc.cache_address = ch.cache_address)
/*
--uncomment this block to have the information only for moving hands caches
where
    ch.rounds_count > 0
    and ch.removed_all_rounds_count > 0
*/
order by total_kb desc

Select '2.5 Ring Buffers'
Select 'Each ring buffer keeps a record of the last number of notifications of a certain kind.'
select
 ring_buffer_type
 , count(*) as [Event count]
from sys.dm_os_ring_buffers
group by ring_buffer_type
order by ring_buffer_type


Select 'See overall state of the server as far as there are SystemHealth records present in this ring buffer.'
Begin
 -- to correlate events, convert timestamps into time
 -- note that the RDTSC counter IS affected by variable clock speeds of the CPU
 declare @ts_now bigint
 select @ts_now = ms_ticks from sys.dm_os_sys_info

 -- "decompose" the records
 select record_id,
  dateadd(ms, -1 * (@ts_now - [timestamp]), GetDate()) as EventTime
  ,SQLProcessUtilization
  ,SystemIdle
  ,100 - SystemIdle - SQLProcessUtilization as OtherProcessUtilization
  ,UserModeTime
  ,KernelModeTime
  ,PageFaults
  ,WorkingSetDelta
  ,MemoryUtilPct
 from (
  select
   record.value('(./Record/@id)[1]', 'int') as record_id,
   record.value('(./Record/SchedulerMonitorEvent/SystemHealth/SystemIdle)[1]', 'int') as SystemIdle,
   record.value('(./Record/SchedulerMonitorEvent/SystemHealth/ProcessUtilization)[1]', 'int') as SQLProcessUtilization,
   record.value('(./Record/SchedulerMonitorEvent/SystemHealth/UserModeTime)[1]', 'int') as UserModeTime,
   record.value('(./Record/SchedulerMonitorEvent/SystemHealth/KernelModeTime)[1]', 'int') as KernelModeTime,
   record.value('(./Record/SchedulerMonitorEvent/SystemHealth/PageFaults)[1]', 'int') as PageFaults,
   record.value('(./Record/SchedulerMonitorEvent/SystemHealth/WorkingSetDelta)[1]', 'int') as WorkingSetDelta,
   record.value('(./Record/SchedulerMonitorEvent/SystemHealth/MemoryUtilization)[1]', 'int') as MemoryUtilPct,
   timestamp
  from (
   select timestamp, convert(xml, record) as record
   from sys.dm_os_ring_buffers
   where ring_buffer_type = N'RING_BUFFER_SCHEDULER_MONITOR'
   and record like '%<SystemHealth>%') as x
  ) as y
 order by record_id desc
End

Select '2.5 Internal Virtual Memory Pressure'
Select 'Virtual address space summary view'
-- generates a list of SQL Server regions
-- showing number of reserved and free regions of a given size
/*
 CREATE VIEW VASummary AS
 SELECT
  Size = VaDump.Size,
  Reserved =  SUM(CASE(CONVERT(INT, VaDump.Base)^0) WHEN 0 THEN 0 ELSE 1
 END),
  Free = SUM(CASE(CONVERT(INT, VaDump.Base)^0) WHEN 0 THEN 1 ELSE 0 END)
 FROM
 (
  --- combine all allocation according with allocation base, don't take into account allocations with zero allocation_base
  SELECT
   CONVERT(VARBINARY, SUM(region_size_in_bytes)) AS Size,
   region_allocation_base_address AS Base
  FROM sys.dm_os_virtual_address_dump
  WHERE region_allocation_base_address <> 0x0
  GROUP BY region_allocation_base_address
  UNION 
     --- we shouldn't be grouping allocations with zero allocation base
     --- just get them as is
  SELECT CONVERT(VARBINARY, region_size_in_bytes),
  region_allocation_base_address
  FROM sys.dm_os_virtual_address_dump
  WHERE region_allocation_base_address  = 0x0
 )
 AS VaDump
 GROUP BY Size
 
 Select 'Available memory in all free regions'
 SELECT SUM(Size*Free)/1024 AS [Total avail mem, KB]
 FROM VASummary
 WHERE Free <> 0

 Select 'Get size of largest availble region. If the largest available region is smaller than 4 MB, your system is likely to be experiencing VAS pressure'
 SELECT CAST(MAX(Size) AS INT)/1024 AS [Max free size, KB]
 FROM VASummary
 WHERE Free <> 0

 Drop VIEW VASummary;
*/

Select '3. I/O Bottlenecks'
Select '3.1 Latch waits'
Select  wait_type,
        waiting_tasks_count,
        wait_time_ms,
        signal_wait_time_ms   --The time between I/O completions until the time the worker is actually scheduled is accounted under the signal_wait_time_ms column.
from sys.dm_os_wait_stats 
where wait_type like 'PAGEIOLATCH%' 
order by wait_type

Select 'Find currently pending I/O requests.'
select
    database_id,
    file_id,
    io_stall,
    io_pending_ms_ticks,
    scheduler_address
from sys.dm_io_virtual_file_stats(NULL, NULL) VFS,
        sys.dm_io_pending_io_requests as PIOR
where VFS.file_handle = PIOR.io_handle


select '3. 2 Examine the queries that generate the most I/Os'
SELECT TOP 10
    (total_logical_reads/execution_count) AS avg_logical_reads,
    (total_logical_writes/execution_count) AS avg_logical_writes,
    (total_physical_reads/execution_count) AS avg_phys_reads,
    execution_count,
    statement_start_offset as stmt_start_offset,
    (SELECT SUBSTRING(text, statement_start_offset/2 + 1,
        (CASE WHEN statement_end_offset = -1
            THEN LEN(CONVERT(nvarchar(MAX),text)) * 2
                ELSE statement_end_offset
            END - statement_start_offset)/2)
     FROM sys.dm_exec_sql_text(sql_handle)) AS query_text,
      (SELECT query_plan from sys.dm_exec_query_plan(plan_handle)) as query_plan
FROM sys.dm_exec_query_stats 
ORDER BY (total_logical_reads + total_logical_writes)/execution_count DESC

Select 'Consider Data Compression to reduce I/O'


Select '4. TempDB Bottlenecks'
Select '4.1 User Object'
Select
    SUM (user_object_reserved_page_count)*8 as user_objects_kb,
    SUM (internal_object_reserved_page_count)*8 as internal_objects_kb,
    SUM (version_store_reserved_page_count)*8  as version_store_kb,
    SUM (unallocated_extent_page_count)*8 as freespace_kb
From sys.dm_db_file_space_usage
Where database_id = DB_ID('tempdb')

Select 'Troubleshooting TempDB Space Issues'
/*Begin
 DECLARE userobj_cursor CURSOR FOR
 select
   S.name + '.' + O.name
 from sys.objects O, sys.schemas S
 where object_id > 100
 and   type_desc = 'USER_TABLE'
 and   O.schema_id = S.schema_id
 
 open userobj_cursor
 
 declare @name varchar(256)
 fetch userobj_cursor into @name
 while (@@FETCH_STATUS = 0)
 begin
  exec sp_spaceused @objname = @name
   fetch userobj_cursor into @name 
 end
 close userobj_cursor
End */


Select '4.2 Version Store'
Select 'Identify longest running transactions that depend on the versions in the version store'
select top 2
    transaction_id,
    transaction_sequence_num,
    elapsed_time_seconds
from sys.dm_tran_active_snapshot_database_transactions
order by elapsed_time_seconds DESC


Select '4.3 Internal Objects'
select
    session_id,
    internal_objects_alloc_page_count,
    internal_objects_dealloc_page_count
from sys.dm_db_session_space_usage
order by internal_objects_alloc_page_count DESC

Select 'Top user sessions that are allocating internal objects, including currently active tasks.'
SELECT
    t1.session_id,
    (t1.internal_objects_alloc_page_count + task_alloc) as allocated,
    (t1.internal_objects_dealloc_page_count + task_dealloc) as 
    deallocated
from sys.dm_db_session_space_usage as t1,
    (select session_id,
        sum(internal_objects_alloc_page_count)
            as task_alloc,
    sum (internal_objects_dealloc_page_count) as
        task_dealloc
      from sys.dm_db_task_space_usage group by session_id) as t2
where t1.session_id = t2.session_id and t1.session_id >50
order by allocated DESC

Select 'Find out which Transact-SQL statement it is and its query plan for a more detailed analysis.'
select
    t1.session_id,
    t1.request_id,
    t1.task_alloc,
    t1.task_dealloc,
    t2.sql_handle,
    t2.statement_start_offset,
    t2.statement_end_offset,
    t2.plan_handle
from (Select session_id,
             request_id,
             sum(internal_objects_alloc_page_count) as task_alloc,
             sum (internal_objects_dealloc_page_count) as task_dealloc
      from sys.dm_db_task_space_usage
      group by session_id, request_id) as t1,
      sys.dm_exec_requests as t2
where t1.session_id = t2.session_id and
     (t1.request_id = t2.request_id)
order by t1.task_alloc DESC


Select 'Excessive DDL and Allocation Operations'
--Begin
-- -- get the current timestamp
-- declare @now datetime
-- select @now = getdate()

-- -- insert data into a table for later analysis
-- insert into analysis..waiting_tasks
--    select
--     session_id,
--     wait_duration_ms,
--     resource_description,
--     @now
--    from sys.dm_os_waiting_tasks
--    where wait_type like 'PAGE%LATCH_%' and
--    resource_description like '2:%'
--End

Select '5. Slow-Running Queries'
Select '5.1 Blocking'
select
    request_session_id as spid,
    resource_type as rt, 
    resource_database_id as rdb,
    (case resource_type
      WHEN 'OBJECT' then object_name(resource_associated_entity_id)
      WHEN 'DATABASE' then ' '
      ELSE (select object_name(object_id)
            from sys.partitions
            where hobt_id=resource_associated_entity_id)
    END) as objname,
    resource_description as rd, 
    request_mode as rm,
    request_status as rs
from sys.dm_tran_locks


Select '5.1.1 Locking Granularity and Lock Escalation'

Select '5.1.2 Identifying Long Blocks'

Select 'Find transaction at head of a blocking chain, their input buffers and the type of blocking locks they hold'
Begin
 declare @blocker_spid smallint
 declare @i_buff_string char(30)
 set nocount on

 if exists (select * from tempdb.dbo.sysobjects where name like '%#blk%')
 drop table #blk

 select spid, blocked, hostname=substring (hostname, 1, 10),progname=substring(program_name, 1, 10), cmd=substring(cmd, 1, 10), status, physical_io, waittype
 into #blk
 from master..sysprocesses (nolock)
 where blocked != 0

 delete from #blk
 where blocked in (select spid from #blk)

 select 'Blocking spid' = spid, --loginame=substring(suser_name(suid),1,10),
 hostname=substring (hostname, 1, 10), progname=substring(program_name, 1,10),
 cmd=substring(cmd, 1, 10), status, physical_io, waittype
 from master..sysprocesses (nolock)
 where spid in
 (select blocked from #blk)

 declare blk_cursor CURSOR FOR SELECT blocked from #blk
 open blk_cursor
 fetch next from blk_cursor into @blocker_spid

 while (@@fetch_status <> -1)
 begin
 select @i_buff_string = ('dbcc inputbuffer (' + convert(char(6),@blocker_spid) +')')
 select 'Below is input buffer for this blocking spid: ', @blocker_spid
 exec (@i_buff_string)
 fetch next from blk_cursor into @blocker_spid
 end
 deallocate blk_cursor
 drop table #blk
End

select '5.1.3 Blocking per Object with sys.dm_db_index_operational_stats'
--Select * from sys.dm_db_index_operational_stats( ... )

select '5.1.4 Overall Performance Effect of Blocking Using Waits'
select top 10 *
from sys.dm_os_wait_stats
order by wait_time_ms desc


select '5.2 Monitoring Index Usage'
select object_id, index_id, user_seeks, user_scans, user_lookups
from sys.dm_db_index_usage_stats
order by object_id, index_id

Select '5.2.1 Indexes of a specific table that has not been used since the last start of SQL Server'
select i.name
from sys.indexes i
where i.object_id=object_id('ApplicationVersion')
and    i.index_id NOT IN  (select s.index_id
                        from sys.dm_db_index_usage_stats s
                        where s.object_id=i.object_id and  
                        i.index_id=s.index_id and
                        database_id = DB_ID() )

Select '5.2.2 All indexes that haven’t been used yet in a specific database'
select object_name(object_id), i.name
from sys.indexes i
where  i.index_id NOT IN (select s.index_id
                          from sys.dm_db_index_usage_stats s
                          where s.object_id=i.object_id and
                          i.index_id=s.index_id and
                          database_id = DB_ID() )
order by object_name(object_id) asc


Select '5.2.3 Find unsed index during current session for tables with data'
Select row_number() Over (order by S.name, object_name(IUS.object_id),I.name) as UnusedIndex
  ,S.name as SchemaName
  ,object_name(IUS.object_id) as TableName
  ,I.name as IndexName
  ,I.index_id
From sys.dm_db_index_usage_stats IUS
Inner Join sys.indexes I
 on IUS.object_id = I.object_id And I.index_id = IUS.index_id
Inner Join sys.objects O
 on I.object_id = O.object_id
Inner Join sys.schemas S
 on O.schema_id = S.schema_id
Inner Join sys.partitions P
 on P.object_id = IUS.object_id And P.index_id = IUS.index_id
Where IUS.database_id = DB_ID()
and  OBJECTPROPERTY(IUS.object_id, 'IsUserTable') = 1
and  I.type_desc = 'nonclustered'
and  I.is_primary_key = 0
and  I.is_unique_constraint = 0
and  P.rows > 1000

 

Last Updated on Sunday, 13 June 2010 13:46
 
DW architecture comparison
Written by Harry Zheng   

The Centralized EDW

 The centralized EDW approach uses a mainframe model with all data and applications residing on a monolithic platform.

Pro:

Single version of the truth

Con:

  • Complex workloads
  • Personnel requirements
  • Slow-to-adapt technology
  • Expensive maintenance
  • Expensive upgrades
  • High total cost of ownership
  • Limited environmental agility

Distributed Independent Data Marts

Pro:

Data marts are highly relevant to the departments using them and the environments are appropriately sized based on need. Departmental ownership is clear.

Con:

  • Data silos
  • Data duplication
  • Impact to operational systems
  • Proliferation of technologies
  • Data management costs

Hub-and-Spoke Architecture

Hub-and-spoke architectures, sometimes referred to as “federated” EDWs, match the business structure of most large enterprises by offering a centralized EDW and a set of dependent data marts.

Pro:

  • The EDW hub allows the enterprise as a whole to set and enforce common standards while enabling analysis and reports that cut across business units.
  • The data mart spokes allow business units to meet their own needs quickly at relatively low cost and also conform to the IT requirements of the overall enterprise.
  •  A well-managed hub-and-spoke architecture allows business units to set their own budgets and priorities, while contributing as necessary to the central EDW.

Con:

  • Difficult to implement
  • Unable to distribute the required data quickly enough to meet the needs of the business units

 

Reference:

http://technet.microsoft.com/en-us/library/dd459147%28SQL.100%29.aspx

Last Updated on Tuesday, 01 June 2010 11:56
 
Change encoding for .bat file included in VS DB project
Written by Harry Zheng   

I was trying to add a DOS batch file to a VS database project to run bcp command to insert data to deployed database:

When I double click the .bat file from windows explorer to run the file, I got this error:

It looks like the default code page, UTF-8, can't be used to save the .bat file.
So I specified the encoding for the bat file to Codepage 1252 instead.
Here is how:
Menu -> File -> Advanced Save Options

Change it to:

Last Updated on Thursday, 13 May 2010 20:46
 
«StartPrev12345678910NextEnd»

Page 1 of 14