Tài liệu SQL Server MVP Deep Dives- P12 pptx

40 370 0
Tài liệu SQL Server MVP Deep Dives- P12 pptx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

396 CHAPTER 29 My favorite DMVs, and why SELECT 'These procedures have not been executed in the past ' + RTRIM(uptime) + ' minutes (the last time SQL started)', sqlserver_start_time FROM AB_Utility.dbo.AB_Uptime(); SELECT [name] = AB_Utility.dbo.AB_GetThreePartName (p.[object_id], DB_ID()), p.create_date, p.modify_date FROM sys.procedures AS p LEFT OUTER JOIN sys.dm_exec_procedure_stats AS ps ON p.[object_id] = ps.[object_id] WHERE ps.[object_id] IS NULL ORDER BY p.[Name]; END GO EXEC dbo.sp_MS_marksystemobject N'dbo.sp_AB_GetUnusedProcedures'; GO USE [your_database]; GO EXEC dbo.sp_AB_GetUnusedProcedures; GO WARNING Although creating objects in the master database has been a relatively safe and well-known method for years, please proceed with the understanding that you may need to change it later It is not documented, not supported, and likely to cease working in some future version of SQL Server The main problem with using undocumented methods is that Microsoft does not need to warn you before they change or remove the functionality; therefore, your next upgrade might end up being a lot more work than you thought Finding inefficient and unused indexes The following query will help you identify indexes in your database that are not used at all, or are used more during maintenance operations than for improving query performance As with the query to find unused procedures, what you with this information will rely heavily on how long SQL Server has been up and running If you restarted SQL Server this morning, then these statistics may not yet represent an adequate sample of your workload And as with the unused procedure code, you will need to create this object in each relevant database, because it returns metadata from the local catalog view sys.indexes (If you want to use the system object technique, the changes to the code are similarly simple.) This code is shown in listing Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross Some interesting applications of my favorite DMVs Listing 397 Measuring the usefulness of indexes USE [your_database]; GO IF OBJECT_ID('dbo.AB_MeasureIndexUsefulness', N'P') IS NOT NULL DROP PROCEDURE dbo.AB_MeasureIndexUsefulness; GO CREATE PROCEDURE dbo.AB_MeasureIndexUsefulness AS BEGIN SET NOCOUNT ON; SELECT 'These indexes have collected statistics for the past ' + RTRIM(uptime) + ' minutes (the last time SQL started)', sqlserver_start_time FROM AB_Utility.dbo.AB_Uptime(); WITH calced AS ( SELECT [object_id], index_id, reads = user_seeks + user_scans + user_lookups, writes = user_updates, perc = CONVERT(DECIMAL(10,2), user_updates * 100.0 / (user_seeks + user_scans + user_lookups + user_updates)) FROM sys.dm_db_index_usage_stats WHERE database_id = DB_ID() ) SELECT [status] = CASE WHEN reads = AND writes = THEN 'Consider dropping : not used at all' WHEN reads = AND writes > THEN 'Consider dropping : only writes' WHEN writes > reads THEN 'Consider dropping : more writes (' + RTRIM(perc) + '% of activity)' WHEN reads = writes THEN 'Reads and writes equal' END, [table] = AB_Utility.dbo.AB_GetTwoPartName( c.[object_id], DB_ID()), [index] = i.Name, c.reads, c.writes FROM calced AS c INNER JOIN sys.indexes AS i ON c.[object_id] = i.[object_id] Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross 398 CHAPTER 29 My favorite DMVs, and why AND c.index_id = i.index_id WHERE c.writes >= c.reads; END GO Note that because the read and write metrics are per operation, not per row, a DML operation that affects 100 rows will only count as one user update in this view Finding inefficient queries The table-valued function in listing will return the top n queries, ordered in descending order by longest average CPU time, longest average elapsed time, highest average reads, highest logical reads, highest writes, or highest number of executions Because this one query does not rely on database-specific catalog views, it can be created in the utility database and called from anywhere (passing database name, number of rows, and ordering preference) You can also add a WHERE clause to restrict the result set to objects matching a certain naming pattern or queries that executed at least n times Listing Finding inefficient queries USE AB_Utility; GO IF OBJECT_ID(N'dbo.AB_GetInefficientQueries', N'IF') IS NOT NULL DROP FUNCTION dbo.AB_GetInefficientQueries; GO CREATE FUNCTION dbo.AB_GetInefficientQueries ( @database_name SYSNAME, @number_of_rows INT, @order_by VARCHAR(15) ) RETURNS TABLE AS RETURN ( SELECT TOP (@number_of_rows) * FROM ( SELECT exec_object = AB_Utility.dbo.AB_GetTwoPartName( est.objectid, est.[dbid]), exec_statement = AB_Utility.dbo.AB_ParseSQLText(est.[text], qs.statement_start_offset, qs.statement_end_offset ), u.sqlserver_start_time, uptime_minutes = u.uptime, execution_count, first_execution_time = qs.creation_time, qs.last_execution_time, avg_cpu_time_milliseconds = qs.total_worker_time / (1000 * qs.execution_count), avg_logical_reads = qs.total_logical_reads / qs.execution_count, Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross Some interesting applications of my favorite DMVs 399 avg_physical_reads = qs.total_physical_reads / qs.execution_count, avg_writes = qs.total_logical_writes / qs.execution_count, avg_elapsed_time_milliseconds = qs.total_elapsed_time / (1000 * qs.execution_count) FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(qs.[sql_handle]) AS est CROSS JOIN AB_Utility.dbo.AB_Uptime() AS u WHERE est.[dbid] = DB_ID(@database_name) ) x ORDER BY CASE @order_by WHEN 'cpu time' THEN avg_cpu_time_milliseconds WHEN 'logical reads' THEN avg_logical_reads WHEN 'physical reads' THEN avg_physical_reads WHEN 'writes' THEN avg_writes WHEN 'elapsed time' THEN avg_elapsed_time_milliseconds WHEN 'executions' THEN execution_count END DESC, exec_object ); GO USE [tempdb]; GO SELECT * FROM AB_Utility.dbo.AB_GetInefficientQueries ( 'msdb', 50, 'cpu time' ) WHERE exec_object NOT LIKE '%sp_get_composite_job_info%' WHERE execution_count >= 50; Finding missing indexes Starting with SQL Server 2005, the database engine started keeping track of indexes that the optimizer would have taken advantage of, if they existed The missing index DMVs should be used only as a guide, and not as the final authority on how you should change your index structures (As with other DMVs, the data does not persist between restarts Also, be careful about relying on data for tables with indexes that have changed recently, as this can also clear out missing index information.) The function in listing will return a slightly more useful output structure to help you determine which tables and indexes you should further investigate for fine tuning This includes information about how long SQL Server has been up, when the last user seek or scan was for that specific query (because it may represent an ad hoc query outside of your normal workload), and the CREATE INDEX DDL if you wanted to follow through with the Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross 400 CHAPTER 29 My favorite DMVs, and why suggestion To use the function, you pass in the database name and the number of rows you want to return Listing Finding missing indexes USE AB_Utility; GO IF OBJECT_ID(N'dbo.AB_GetMissingIndexes', N'IF') IS NOT NULL DROP FUNCTION dbo.AB_GetMissingIndexes GO CREATE FUNCTION dbo.AB_GetMissingIndexes ( @database_name SYSNAME, @number_of_rows INT ) RETURNS TABLE AS RETURN ( SELECT TOP (@number_of_rows) *, must give credit to Tibor Karazsi here: [statement] = 'CREATE INDEX []' + ' ON ' + [table] + ' (' + COALESCE(eq + COALESCE(', ' + iq, ''), iq) + ')' + COALESCE(' INCLUDE(' + ic + ');', ';') FROM ( SELECT [table] = AB_Utility.dbo.AB_GetTwoPartName( d.[object_id], d.database_id), eq = d.equality_columns, iq = d.inequality_columns, ic = d.included_columns, relative_benefit = (s.user_seeks + s.user_scans) * (s.avg_total_user_cost * s.avg_user_impact), s.user_seeks, s.user_scans, s.last_user_seek, s.last_user_scan FROM sys.dm_db_missing_index_details AS d INNER JOIN sys.dm_db_missing_index_groups AS g ON d.index_handle = g.index_handle INNER JOIN sys.dm_db_missing_index_group_stats AS s ON g.index_group_handle = s.group_handle WHERE d.database_id = DB_ID(@database_name) ) x CROSS JOIN AB_Utility.dbo.AB_Uptime() ORDER BY relative_benefit DESC ); Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross DMV categories in SQL Server 401 GO SELECT * FROM AB_Utility.dbo.AB_GetMissingIndexes ( 'Org00010001', 50 ); DMV categories in SQL Server Table lists the DMV categories in both SQL Server 2005 and SQL Server 2008 Table lists the new DMV categories in SQL Server 2008 Table DMV categories in SQL Server 2005 and 2008 DMV category DMVs URL for more information Common Language Runtime (CLR) sys.dm_clr_* http://msdn.microsoft.com/en-us/ library/ms179982.aspx Database sys.dm_db_* http://msdn.microsoft.com/en-us/ library/ms181626.aspx Database mirroring sys.dm_db_mirroring_* http://msdn.microsoft.com/en-us/ library/ms173571.aspx Execution sys.dm_exec_* http://msdn.microsoft.com/en-us/ library/ms188068.aspx Full-text search sys.dm_fts_* http://msdn.microsoft.com/en-us/ library/ms174971.aspx Indexes sys.dm_db[_missing|_index_* http://msdn.microsoft.com/en-us/ library/ms187974.aspx Input/output (I/O) sys.dm_io_* http://msdn.microsoft.com/en-us/ library/ms190314.aspx Query notifications sys.dm_qn_* http://msdn.microsoft.com/en-us/ library/ms187407.aspx Replication sys.dm_repl_* http://msdn.microsoft.com/en-us/ library/ms176053.aspx Service broker sys.dm_broker_* http://msdn.microsoft.com/en-us/ library/ms176110.aspx SQL Server operating system sys.dm_os_* http://msdn.microsoft.com/en-us/ library/ms176083.aspx Transactions sys.dm_tran_* http://msdn.microsoft.com/en-us/ library/ms178621.aspx Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross 402 CHAPTER 29 Table My favorite DMVs, and why New DMV categories in SQL Server 2008 DMV URL Change data capture sys.dm_cdc_* http://msdn.microsoft.com/ en-us/library/bb522478.aspx Extended events sys.dm_xe_* http://msdn.microsoft.com/ en-us/library/bb677293.aspx Object (dependency) sys.dm_sql_* http://msdn.microsoft.com/ en-us/library/bb630390.aspx Resource governor sys.dm_resource_governor_* http://msdn.microsoft.com/ en-us/library/bb934218.aspx Security sys.dm_[audit|cryptographic|etc]_* http://msdn.microsoft.com/ en-us/library/bb677257.aspx Summary Gone are the days of running DBCC commands and system stored procedures over and over again, and keeping links to Profiler and Performance Monitor on every machine’s desktop, when trying to peek into the usage characteristics of our SQL Server instances I hope I have provided a glimpse of how much power we have been given through DMVs and DMFs, and that I have inspired you to use them more often when observing usage or troubleshooting performance issues About the author Aaron Bertrand is the Senior Data Architect at One to One Interactive, a global marketing agency headquartered in Boston, Massachusetts At One to One, Aaron is responsible for database design and application architecture Due to his commitment to the community, shown through blogging at http://www.sqlblog.com, peer-to-peer support on forums and newsgroups, and speaking at user group meetings and code camps, he has been awarded as a Microsoft MVP since 1998 Aaron recently published a technical white paper for Microsoft, detailing how to use the new Resource Governor feature in SQL Server 2008 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross 30 Reusing space in a table Joe Webb People who have switched to Microsoft SQL Server from Microsoft Access sometimes ask, “If I delete a bunch of rows, I need to compact my SQL Server database?” It’s been many years since I’ve used Access, but I still remember the reason for their concern Access would continually add rows to the end of the table If some, or even all, of the rows were deleted from the table, Access wouldn’t reuse the space It kept adding rows to the end of the table and never backfilled the holes Compacting the Access database file would get rid of the holes Understanding how SQL Server automatically reuses table space I’m not an expert in Access, and I’m certainly not knocking it I haven’t even used Access since v2.0 back in the 1990s This behavior may have changed since then, or perhaps I misremember, but suffice it to say that with SQL Server this is not an issue But don’t take my word for it Let’s consider an example to prove the point To set up the example, let’s create a table with three columns and then populate it with test data The T-SQL code for doing this is shown in listing Listing Creating and populating the dbo.Test table USE tempdb ; GO create a test table CREATE TABLE dbo.Test ( col1 INT ,col2 CHAR(25) ,col3 VARCHAR(4000) ) ; create some test data DECLARE @cnt INT ; SET @cnt = ; 403 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross 404 CHAPTER 30 Reusing space in a table WHILE @cnt < 1000 BEGIN SELECT @cnt = @cnt + ; INSERT VALUES dbo.Test ( col1,col2,col3 ) ( @cnt ,'test row # ' + CAST(@cnt AS VARCHAR(10)) + 'A' ,REPLICATE('ABCD', ROUND(RAND() * @cnt, 0)) ) ; END The CREATE TABLE statement creates a table called Test as part of the dbo schema in the tempdb database The table is composed of three columns The first is an integer, the second is a fixed length character string that contains 25 characters, and the third and final column is a variable length character string that can contain up to 1900 characters To add test data, we will use a simple INSERT statement The INSERT statement has been placed inside a WHILE loop and is executed 1,000 times Note that the last column in the table will vary in length from zero to a maximum of 4,000 Statistically, it should average around 1,000 characters Let’s view the contents of the table to make sure we have what we think we have We can this by running a SELECT statement to retrieve the data, as shown in listing The results of the query are shown in figure Listing Querying the dbo.Test table view the table SELECT * FROM dbo.Test ; To examine the amount of space the table consumes, we’ll use a Dynamic Management View (DMV) called sys.dm_db_index_physical_stats DMVs were first introduced in SQL Server 2005 and have been continued in SQL Server 2008 (For more on DMVs, see chapter 29, “My favorite DMVs, and why,” by Aaron Bertrand.) NOTE The scripts that make use of DMVs will not work in SQL Server 2000 The query in listing returns a single row of data with four columns—the allocation unit type, the page count, the average page space used as a percentage, and the total Figure Results from dbo.Test table Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross Understanding how SQL Server automatically reuses table space 405 number of rows in the dbo.Test table The alloc_unit_type_desc column describes the allocation unit type: valid values are IN_ROW_DATA, LOB_DATA, or ROW_OVERFLOW_DATA (see Books Online for a detailed explanation of these terms) The page_count column indicates the total number of data pages used by the table for IN_ROW_DATA (that is, the allocation unit that stores the table rows in our example) The avg_page_ space_used_in_percent column reports the average percentage of space used in all data pages in the IN_ROW_DATA allocation type The record_count intuitively contains the number of rows contained in the table Listing Examining the space used by the dbo.Test table check the size of the table SELECT alloc_unit_type_desc ,page_count ,avg_page_space_used_in_percent ,record_count FROM sys.dm_db_index_physical_stats( DB_ID() ,OBJECT_ID(N'dbo.Test') ,NULL ,NULL ,'Detailed') ; Figure displays the results of the DMV query As you can see on my test system, 158 data pages are used to store the 1,000 rows and each data page is, on average, 82.1 percent full Figure Using a DMV to review space used To continue with the example, let’s delete half of the rows in our dbo.Test table and see what happens to the space used by the table The T-SQL script in listing uses the modulo operator, represented by the percent sign in T-SQL, to delete each row where the value in the first column, col1, is an odd number So we are deleting every other row in the table Listing Deleting the odd-numbered rows delete the odd rows DELETE FROM Test WHERE col1 % = view the table SELECT * Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Licensed to Kerri Ross ... categories in SQL Server 401 GO SELECT * FROM AB_Utility.dbo.AB_GetMissingIndexes ( ''Org00010001'', 50 ); DMV categories in SQL Server Table lists the DMV categories in both SQL Server 2005 and SQL Server. .. table partitioning Our focus will be on SQL Server 2008 and SQL Server 2005 Table partitioning was introduced with SQL Server 2005 and enhanced a bit in SQL Server 2008, but the overall architecture... Joe Webb People who have switched to Microsoft SQL Server from Microsoft Access sometimes ask, “If I delete a bunch of rows, I need to compact my SQL Server database?” It’s been many years since

Ngày đăng: 15/12/2013, 13:15

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan