深入瞭解SQL Server動態管理視圖

  隨着SQL Server 2005版本的發佈,帶來了一種新的用於訪問系統和數據庫信息的方式,而無需創建複雜的查詢或直接訪問系統表。通過使用SQL Server動態管理視圖(DMVs),你可以查看SQL Server的實例信息,比如實例運行在什麼系統上、實例中有那些數據庫。

  你可以在Transact-SQL語句中引用你想要查看的視圖名稱來調用DMVs。所有的DMVs都存放在SYS架構中,這個預定義架構包含了系統視圖。它們以字符dm_開頭,如sys.dm_os_hosts。

  與其他類型的視圖一樣,SQL Server DMVs返回一個指定數據類型的列集合。但是,一個DMV的架構會隨着SQL Server版本的變化而變化。因此,當編寫調用DMV的代碼時,你應該指定列名而不是使用類似SELECT * FROM view_name之類的語法。

  SQL Server動態管理視圖可分爲兩大類:一類是描述數據庫級別的信息,另一類是描述服務器級別的信息。在本文中,我將演示如何使用前者,後者我將會在以後的文章中加以闡述。本文例子所使用的系統環境是一個創建在本地的SQL Server 2008實例。例子中引用的數據庫是AdventureWorks 2008示例數據庫,除了一個例子使用了SQL Server Reporting Services數據庫。對於每一個例子,我都會列出語句運行的結果集。很可能你的結果集會有所不同,這取決於你在哪種系統上運行SQL Server以及如何修改數據庫的。

  與數據庫相關的SQL Server DMVs

  我們查看的第一個SQL Server DMV是sys.dm_db_partition_stats,它返回當前數據庫中的分區信息,每個分區一行。(如果一個索引、一個堆或者一個沒有索引的表未被分區,它被認爲是一個分區。)該視圖返回的信息包括分區使用的頁面數量和總行數。在下面的SELECT語句中,我使用這個DMV來獲取AdventureWorks 2008數據庫中Production.Product表的分區信息:

  USE AdventureWorks2008;
  GO
  SELECT
  index_id AS IndexID,
  partition_number AS PartitionNum,
  used_page_count AS UsedPageCount,
  row_count AS TotalRows
  FROM
  sys.dm_db_partition_stats
  WHERE
  object_id = OBJECT_ID('Production.Product')
  ORDER BY
  IndexID,
  PartitionNum;

  如語句所示,sys.dm_db_partition_stats動態管理視圖返回的信息首先是索引或堆的識別號然後是分區號。換句話說,定義的分區號與特定的索引或堆相關,所以每個索引或堆可以有一個或多個分區。(這個分區號不同於數據庫分配給每個分區的獨一無二的分區ID。)

  緊接着索引ID和分區號,還將返回該分區的頁面總數和使用的總行數,結果如下表所示:

IndexID

ParitionNum

UsedPageCount

TotalRows

1

1

15

504

2

1

4

504

3

1

5

504

4

1

4

504

  如上表所示,在PRODUCT表中每個索引或堆都只有一個分區,每個分區有504行。

  接下來的動態管理視圖,我會介紹sys.dm_sql_referenced_entities。該視圖返回指定對象所引用的用戶定義的數據庫對象集合,每個對象一行。例如,如果一個存儲過程引用了用戶定義的表,則動態管理視圖將爲每個表返回一行。

  實際上,sys.dm_sql_referenced_entities並不是一個視圖,它是一個函數。在下面的SELECT語句中,我使用sys.dm_sql_referenced_entities函數來檢索觸發器iuPerson所引用的對象列表,如下所示:

  USE AdventureWorks2008;
  GO SELECT referenced_schema_name AS SchemaName,
  referenced_entity_name AS EntityName,
  referenced_class_desc AS ClassName
  FROM sys.dm_sql_referenced_entities
  ('Person.iuPerson', 'OBJECT')
  ORDER BY
  SchemaName,
  EntityName;

  觸發器iuPerson是Person架構的一部分,與Person表相關。當我調用該函數時,需要指定觸發器名稱和OBJECT參數選項。如果它是一個數據庫級觸發器,則需要指定DATABASE_DDL_TRIGGER參數選項。如果它是一個服務器級觸發器,則需要指定SERVER_DDL_TRIGGER參數選項。下表顯示SELECT語句返回的信息:

SchemaName

EntityName

ClassName

NULL

Person

OBJECT_OR_COLUMN

NULL

Person

OBJECT_OR_COLUMN

Demographics

exist

OBJECT_OR_COLUMN

Person

Person

OBJECT_OR_COLUMN

Person

Person

OBJECT_OR_COLUMN

Person

Person

OBJECT_OR_COLUMN

  請注意,返回的是AdventureWorks 2008數據庫中iuPerson觸發器所引用對象的架構名稱、實體名稱和類別。

  另一個你可能會發現有用的數據庫管理函數是sys.dm_sql_referencing_entities,它返回數據庫中的某個實體引用另一個用戶定義實體的信息,每個實體一行。例如,在下面的語句中使用該函數來檢索Production.ProductInventory表所引用對象的架構、實體及類別:

  USE AdventureWorks2008;
  GO
  SELECT
  referencing_schema_name AS SchemaName,
  referencing_entity_name AS EntityName,
  referencing_class_desc AS ClassName
  FROM
  sys.dm_sql_referencing_entities
  ('Production.ProductInventory', 'OBJECT')
  ORDER BY
  SchemaName,
  EntityName;

  與前面的例子中,我提供的參考對象是ProductInventory表,並使用了OBJECT參數選項。下面的結果表明,該表引用了四個用戶定義的對象:

SchemaName

EntityName

ClassName

dbo

fn_inventory

OBJECT_OR_COLUMN

dbo

ufnGetStock

OBJECT_OR_COLUMN

Production

CK_ProductInventory_Bin

OBJECT_OR_COLUMN

Production

CK_ProductInventory_Shelf

OBJECT_OR_COLUMN

  還有一個動態管理函數是sys.dm_db_index_physical_stats,它返回指定表或視圖的索引和數據的大小和碎片信息。在下面的SELECT語句中,我將數據庫名稱和表名稱作爲函數的前兩個參數:

  USE AdventureWorks2008;
  GO
  SELECT
  index_id AS IndexID,
  index_type_desc AS IndexType,
  fragment_count AS FragCount,
  page_count AS TotalPages
  FROM
  sys.dm_db_index_physical_stats
  (DB_ID('AdventureWorks2008'), OBJECT_ID('Person.Person'),
  NULL, NULL, NULL)
  ORDER BY
  IndexID;

  正如你所看到的,sys.dm_db_index_physical_stats還需要三個額外的參數,在例子中已經被指定爲NULL值。這三個參數分別代表:索引ID、分區號和用於獲取統計信息的掃描模式。因爲我想了解表上所有索引和分區的信息,我爲前兩個參數指定了NULL值。關於模式,NULL值表示將使用有限的掃描模式,而不是詳盡或採樣掃描模式。SELECT語句返回以下結果:

IndexID

IndexType

FragCount

TotalPages

1

CLUSTERED INDEX

5

3807

2

NONCLUSTERED INDEX

2

103

3

NONCLUSTERED INDEX

2

57

256000

PRIMARY XML INDEX

1

3

256001

PRIMARY XML INDEX

7

2152

256002

XML INDEX

33

1386

256003

XML INDEX

33

1385

256004

XML INDEX

35

1386

  返回結果包括與Person表相關的索引ID、索引類型、碎片數量和頁數。

  現在,讓我們回到SQL Server動態管理視圖。動態管理視圖sys.dm_db_index_usage_stats返回自上一次啓動SQL Server服務啓動以來不同的索引操作類型的統計信息,如檢索和掃描。在下面的SELECT語句中,我查看本地SQL Server實例中最近的索引操作使用的統計信息。

  USE AdventureWorks2008;
  GO
  SELECT
  OBJECT_NAME(object_id) AS ObjectName,
  index_id AS IndexID,
  user_seeks AS UserSeeks,<
user_scans AS UserScans
  FROM
  sys.dm_db_index_usage_stats
  WHERE
  database_id = DB_ID('AdventureWorks2008')
  ORDER BY
  ObjectName,
  IndexID;

  注意,對於每個操作可查詢到對象的名稱、該對象對應的索引ID以及用戶檢索和掃描的次數。下面的結果表明,自SQL Server服務實例啓動以來只有較少數量的檢索和掃描:

ObjectName

IndexID

UserSeeks

UserScans

Document

1

1

0

JobCandidate

1

1

0

ProductReview

1

1

0

SalesOrderHeader

1

0

1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章