dmv 统计数据库io

介绍 (Introduction)

In the last two articles on dynamic management views in SQL Server, Discovering SQL server instance information using system views and Discovering more SQL Server information using the built-in dynamic management views (DMVs), we used DMVs to discover a fair bit of information about the SQL Server instance we’re connected to. In this article, we’ll begin diving in to database specifics. There is a lot of territory to cover! We’ll also use several of the built-in functions that come with SQL Server.

在有关SQL Server中动态管理视图的最后两篇文章中, 使用系统视图 发现SQL Server 实例信息和使用内置动态管理视图(DMV)发现更多SQL Server信息 ,我们使用DMV查找了有关以下内容的相当多的信息:我们连接到SQL Server实例。 在本文中,我们将开始深入研究数据库的细节。 有很多领域要覆盖! 我们还将使用SQL Server附带的一些内置函数。

我在哪里? (Where am I?)

A good place to start is to figure out what database you are connected to, if any. That part is easy:

一个不错的起点是弄清楚您要连接的数据库(如果有)。 这部分很简单:


SELECT DB_NAME() AS DatabaseName;

The DB_NAME function returns the name of the database to which you are currently connected, if you do not specify any parameters. Before you run this, though, open a new connection to SQL Server in SSMS, right-click the instance node in object explorer (just above Databases) and select “New Query”. In the query window that opens, type the command above. When I do that I get:

如果未指定任何参数,则DB_NAME函数将返回当前连接的数据库的名称。 但是,在运行此命令之前,请在SSMS中打开与SQL Server的新连接,右键单击对象资源管理器中的实例节点(位于数据库上方),然后选择“新建查询”。 在打开的查询窗口中,键入上面的命令。 当我这样做时,我得到:

Since I’m not connected to any database, that tells me that the default database for my user id is “master”. If, however, I do the same operation after right-clicking on a specific database – e.g. AdventureWorks2014 – the results now show:

由于我没有连接到任何数据库,因此可以知道我的用户ID的默认数据库为“ master”。 但是,如果在右键单击特定数据库(例如AdventureWorks2014)后执行相同的操作,则结果将显示:

Unsurprising, to say the least! There’s another function, ORIGINAL_DB_NAME, which can display different results. It shows the database to which you were connected when the connection was first made. To show how they can be different, first open a new connection and explicitly specify a database. I chose “master”. Then run a script like this one:

毫不奇怪,至少可以说! 还有另一个函数ORIGINAL_DB_NAME,可以显示不同的结果。 它显示了首次建立连接时要连接到的数据库。 要显示它们之间的不同之处,请首先打开一个新连接并显式指定一个数据库。 我选择了“大师”。 然后运行这样的脚本:


SELECT DB_NAME() AS DatabaseName;
GO
USE AdventureWorks2014;
GO
SELECT DB_NAME()          AS CurrentDBName, ORIGINAL_DB_NAME() AS OriginalDBName;

You should see something like this:

您应该会看到以下内容:

Notice that SSMS reports both the original and current database names.

请注意,SSMS报告了原始数据库名称和当前数据库名称。

Every database also has an id value, which is an integer. In fact, all objects in SQL Server have an id. Some (like database objects) are used so frequently that they have a dedicated function to retrieve it. So there is a DB_ID function to return the id of a database given the name, or the current database id, if the name is omitted. The ORIGINAL_DB_NAME function does not have a corresponding ORIGINAL_DB_ID function, but we can get the id easily enough like this:

每个数据库还具有一个ID值,它是一个整数。 实际上,SQL Server中的所有对象都有一个ID。 一些对象(如数据库对象)被频繁使用,以至于它们具有专用的功能来检索它。 因此,有一个DB_ID函数可以返回给定名称的数据库的ID,如果省略名称,则返回当前数据库的ID。 ORIGINAL_DB_NAME函数没有相应的ORIGINAL_DB_ID函数,但是我们可以很容易地获得id,如下所示:


SELECT ORIGINAL_DB_NAME()        AS DatabaseName, DB_ID(ORIGINAL_DB_NAME()) AS DatabaseID;

An interesting side-note is that DB_ID and DB_NAME are complementary. That is:

一个有趣的旁注是DB_ID和DB_NAME是互补的。 那是:


DB_ID(DB_NAME([database id]))  = DB_ID([database name]) 

and


DB_NAME(DB_ID([database name]) = DB_NAME([database id])

For any given database, even if you omit the parameters (in which case the functions apply to the current database.

对于任何给定的数据库,即使您省略了参数(在这种情况下,这些功能也适用于当前数据库。

By the way, if you’re not sure what the default database is for your SQL Server login id, this little query will expose it:

顺便说一句,如果您不确定SQL Server登录ID的默认数据库是什么,此查询将公开它:


SELECT u.NAME AS UserName, l.dbname AS DefaultDatabase
FROM sys.sysusers u
JOIN sys.syslogins l ON u.sid = l.sid
WHERE u.NAME = USER_NAME(;

该数据库如何配置? (How is this database configured?)

SQL Server has lots of properties for configuring the behavior of a database. You can, of course view them at any time in SSMS but this article is all about using the built-in functions to gather information. The function DATABASEPROPERTYEX is the one you want to use here. There is a long and growing list of database properties so we won’t look at all of them. To whet your appetite, here are some I find interesting:

SQL Server具有许多用于配置数据库行为的属性。 您当然可以在SSMS中随时查看它们,但是本文全部涉及使用内置函数来收集信息。 函数DATABASEPROPERTYEX是您要在此处使用的函数。 数据库属性列表越来越长,因此我们不会一一列举。 为了激发您的胃口,我发现一些有趣的东西:

Collation Default database collation
Comparison Style Ignore or respect case, accents Kana and width
Recovery Recover mode
Status Offline, recovering, restoring etc.
Updateability Read only or read write
校对 默认数据库整理
比较风格 忽略或尊重大小写,强调假名和宽度
复苏 恢复模式
状态 离线,恢复,还原等
可更新性 只读或读写

For example, using AdventureWorks as a database, this will show me the collation:

例如,使用AdventureWorks作为数据库,这将向我显示排序规则:


SELECT  DATABASEPROPERTYEX(DB_NAME(), 'Collation') AS Collation;

Result:

结果:

These properties are also exposed by the system catalog view sys.databases. There is at least one property that you can see using the latter that you is not shown by the former: Compatibility Level

这些属性也由系统目录视图sys.databases公开。 您可以看到至少一个使用前者未显示的属性:兼容性级别

So, for AdventureWorks, I can run:

因此,对于AdventureWorks,我可以运行:


SELECT compatibility_level  AS CompatabilityLevel
FROM sys.databases
WHERE name = 'AdventureWorks2014';

Whether you should use DATABASEPROPERTYEX or sys.databases depends on your use case. For simple, single-property enquiries, I find the function easier to use. Get familiar with both!

是否应使用DATABASEPROPERTYEX或sys.databases取决于您的用例。 对于简单的单属性查询,我发现该函数更易于使用。 熟悉两者!

To see:

查看:

谁拥有这个数据库? (Who owns this database?)

In SQL Server, every database has an owner. By default, if you create a new database, the owner will be the login id you are currently using. If you are restoring or attaching a database from another server, the owner might not be so obvious. The first thing to understand is that SQL Server uses a level of indirection to record the owner of a database. To put it simply, a database is owned by one of the database principles and that principle is associated with a particular login. The database principle that is the owner is always dbo.

在SQL Server中,每个数据库都有一个所有者。 默认情况下,如果您创建一个新数据库,则所有者将是您当前正在使用的登录ID。 如果要从其他服务器还原或附加数据库,则所有者可能不是很明显。 首先要了解的是,SQL Server使用一种间接级别来记录数据库的所有者。 简而言之,数据库属于其中一种数据库原理,并且该原理与特定的登录名相关联。 作为所有者的数据库原则始终是dbo 。

For example, I have the AdventureWorks2014 database I restored from CodePlex. If I look for dbo in the database principles:

例如,我有从CodePlex恢复的AdventureWorks2014数据库。 如果我在数据库原理中寻找dbo:


SELECT sid FROM sys.database_principals WHERE name = 'dbo';

I get: 0x0105000000000005150000003704E0A8012294A2BD738156E9030000

我得到:0x0105000000000005150000003704E0A8012294A2BD738156E9030000

If I try to look up that sid:

如果我尝试查找该sid:


SELECT * from sys.syslogins
WHERE sid = '0x0105000000000005150000003704E0A8012294A2BD738156E9030000';

I get no results! Why? Because I restored the database, which was created on another server. The sid associated with the database principle dbo does not exist on my server. So, the sid in sys.database_principles might not always be accurate. However I can use this query instead:

我没有结果! 为什么? 因为我还原了在另一台服务器上创建的数据库。 与数据库原理dbo相关的sid在我的服务器上不存在。 因此,sys.database_principles中的sid可能并不总是准确的。 但是我可以改用以下查询:


SELECT SUSER_SNAME(owner_sid) FROM sys.databases
WHERE name = 'AdventureWorksDW2014';

I get:

我得到:

Which is… me!

那是……我!

To reconcile this situation, I can change the ownership of the database easily:

为了调和这种情况,我可以轻松更改数据库的所有权:


ALTER AUTHORIZATION ON DATABASE::AdventureWorksDW2014 TO sa;

Note: Making sa the owner of your databases is usually a good idea. The sa login is restricted and login is disabled by default. Now this query will work properly:

注意:让sa成为数据库的所有者通常是一个好主意。 sa登录名受限制,默认情况下禁用登录。 现在,此查询将正常工作:


SELECT d.name as DBName, u.name
FROM sys.databases d
JOIN sys.sysusers u
ON d.owner_sid = u.sid
WHERE d.name = 'AdventureWorks2014DW';

这里还有其他用户吗? (Are there other users here?)

We can use sys.database_principals to see if there are other users with permissions in the database:

我们可以使用sys.database_principals来查看数据库中是否还有其他具有权限的用户:


SELECT SUSER_NAME(p.sid) AS Name, type_desc as [Type]
FROM sys.database_principals p
JOIN sys.syslogins l
ON p.sid = l.sid
WHERE type_desc in ('SQL_USER', 'WINDOWS_USER')
AND SUSER_NAME(p.sid) IS NOT NULL;

If this query returns rows, it may warrant a closer look. Does it make sense that actual SQL Server or individual Windows logins have specific permissions in your database? Often, it does not make sense at all! There is a good principle known as double-abstraction which works like this:

如果此查询返回行,则可能需要仔细查看。 实际SQL Server或单个Windows登录名在您的数据库中具有特定权限是否有意义? 通常,这根本没有任何意义! 有一个称为双抽象的好原理,其工作原理如下:

  1. All users belong to AD groups or local groups on the server (limit these!). 所有用户都属于服务器上的AD组或本地组(限制这些!)。
  2. Only the groups have permission to login to the server or connect to a database. 只有组才有权登录服务器或连接到数据库。
  3. In the database, database roles (to be covered later) control permissions. 在数据库中,数据库角色(稍后将介绍)控制权限。
  4. Permissions are granted to roles. 权限被授予角色。
  5. Groups are added to roles. 组已添加到角色。

If the query above shows an end-user, whether Windows or a SQL Server login, its time to ask serious questions. Each such user is a potential security hole and a maintenance headache. Managing users at the group level and permissions at the role level, then joining the two by adding groups to roles, makes auditors happy (well, not as unhappy as usual!) and user maintenance much easier.

如果上面的查询显示的是最终用户(无论是Windows还是SQL Server登录名),是时候提出严重问题了。 每个这样的用户都是潜在的安全漏洞和维护难题。 管理在组级用户和权限的角色等级,然后通过添加组角色连接两个,使得审计师快乐(当然,不是作为联合国快乐像往常一样!)和用户的维护更加容易。

In a future article, we’ll dig into what permissions are actually assigned to users, groups and roles. For now, let’s look at another area of interest, storage.

在以后的文章中,我们将深入研究实际为用户,组和角色分配的权限。 现在,让我们看一下另一个感兴趣的领域,即存储。

哪里都在哪 (Where is everything?)

Objects in databases live in partitions. For simple databases, you might not even notice, since everything lives in the PRIMARY partition. The view sys.partitions gives us insight into what is where:

数据库中的对象位于分区中。 对于简单的数据库,您甚至可能不会注意到,因为所有内容都驻留在PRIMARY分区中。 sys.partitions视图使我们可以洞悉哪里:


SELECT OBJECT_NAME(object_id) AS ObjectName, * FROM sys.partitions

The first time you run this, you’ll see a long list of objects beginning with “sys”. If you want to see non-system items, add

第一次运行此命令时,会看到一长串以“ sys”开头的对象。 如果要查看非系统项目,请添加


WHERE OBJECT_NAME(object_id) NOT LIKE 'sys%'

Now, you should be able to see some table and index names. On my test machine, in the AdventureWorks database, I see results beginning with:

现在,您应该能够看到一些表和索引名称。 在我的测试机上,在AdventureWorks数据库中,我看到以以下内容开头的结果:

There are a number of interesting items here, but let’s look at just two for now:

这里有很多有趣的项目,但现在让我们看一下两个:

  1. Index_id has just three values, 0, 1, or 2 for heaps, clustered indexes, and non-clustered indexes respectively. So, I can tell that “Currency” is a clustered index (a table) and DatabaseLog is a non-clustered index.

    Index_id仅具有三个值,分别是堆,聚集索引和非聚集索引的0、1或2。 因此,我可以说“ Currency”是一个聚集索引(一个表),而DatabaseLog是一个非聚集索引。

  2. Rows is the approximate number of rows in the partition for the object in that row of the results. Sometimes the approximate number of rows is enough. On a busy, large table, the actual number of rows may be changing minute by minute or even second by second or even faster. To obtain the actual number of rows for a table at some point in time you’d need a query like this:

    行数是该结果行中对象在分区中的大概行数。 有时,大约的行数就足够了。 在一个繁忙的大桌子上,实际的行数可能每分钟都在变化,甚至每秒都在变化,甚至更快。 要在某个时间点获取表的实际行数,您需要这样的查询:

    
    SELECT COUNT(*) FROM myschema.mytable WITH (TABLOCK)

    However, that’s the sort of query you don’t want to run against a busy table! It’s nice to know that you can a get “good-enough” row count from sys.partitions. If you use this method, and you also have more than one partition, be sure to add up the row counts for the tables or indexes you’re interested in.

    然而,这是排序查询您不想对一个繁忙的表运行! 很高兴知道您可以从sys.partitions获得“足够好”的行数。 如果您使用此方法,并且还具有多个分区,请确保将您感兴趣的表或索引的行计数加起来。

The last system view I’ll introduce in this article is sys.database_files. It shows, surprise! The files used by the database. This may be a list of just two files or a much longer list if you use multiple partitions.

我将在本文中介绍的最后一个系统视图是sys.database_files 。 它表明,令人惊讶! 数据库使用的文件。 这可能是仅两个文件的列表,或者如果使用多个分区,则可能是更长的列表。


SELECT * FROM sys.database_files

Will get you started.

会帮助您入门。

Next time, I’ll dig into user permissions, a somewhat complicated but extremely important topic, especially in today’s security-conscious world.

下次,我将深入探讨用户权限,这是一个有点复杂但极为重要的主题,尤其是在当今注重安全性的世界中。

Other articles in this series:

本系列的其他文章:

  • Discovering SQL server instance information using system views 使用系统视图发现SQL Server实例信息
  • Discovering more SQL Server information using the built-in dynamic management views (DMVs) 使用内置的动态管理视图(DMV)发现更多SQL Server信息
  • How to track SQL Server database space usage with built-in functions and DMVs如何使用内置函数和DMV跟踪SQL Server数据库空间使用情况

翻译自: https://www.sqlshack.com/discovering-database-specific-information-using-built-in-functions-and-dynamic-management-views-dmvs/

dmv 统计数据库io

dmv 统计数据库io_使用内置功能和动态管理视图(DMV)发现特定于数据库的信息相关推荐

  1. dmv io读写高的sql_使用内置的动态管理视图(DMV)发现更多SQL Server信息

    dmv io读写高的sql 介绍 (Introduction) This is the second article in a continuing series on the many system ...

  2. 数据库 - mysql内置功能

    mysql内置功能: 1.视图 2.触发器 3.存储过程 4.事务 5.函数 一.视图 介绍: 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名], 用户使用时只需 ...

  3. Excel:利用Excel内置功能实现对某列表格按照条件进行升降序排列

    Excel:利用Excel内置功能实现对某列表格按照条件进行升降序排列 目录 实现功能 实现方法 实现功能 利用Excel内置功能实现对某列表格按照设置条件进行升降序排列 实现方法

  4. mysql 内置功能 存储过程介绍

    存储过程介绍 就是mysql内置功能把逻辑写好 的功能给封装好,封装成一个接口名,把接口名丢给应用程序,应用程序直接调用接口名实现一系列增删改查功能 这个接口叫存储过程 基于存储过程封装成一个功能 存 ...

  5. mysql 内置功能 存储过程 目录

    mysql 内置功能 存储过程介绍 mysql 内置功能 存储过程 创建无参存储过程 mysql 内置功能 存储过程 创建有参存储过程 mysql 内置功能 存储过程 删除存储过程 转载于:https ...

  6. Parnassus书签,增强的导航功能简化内置功能

    Parnassus书签,增强的导航功能简化内置功能 什么是Parnassus书签,导航器和代码编辑器? Parnassus书签通过新的增强的导航功能简化了IDE的内置功能.使用Ctrl + B标记-一 ...

  7. MySQL学习思维导图(MySQL简介、SQL基础命令、约束、单表查询、多表查询、内置函数、存储过程、视图、事务、索引)

    MySQL学习思维导图 内容包括:MySQL简介.SQL基础命令.约束.单表查询.多表查询.内置函数.存储过程.视图.事务.索引 文章目录 MySQL学习思维导图 一.MySQL简介 二.SQL基础命 ...

  8. Spring MVC-09循序渐进之文件上传(基于Servlet3.0+内置功能)

    概述 测试 源码 概述 Spring MVC-09循序渐进之文件上传(基于Apache Commons FileUpload) 上篇博文我们说了基于Apache Commons FileUpload的 ...

  9. mysql5720_Mysql内置功能《五》 函数

    一 函数 MySQL中提供了许多内置函数,例如: 一.数学函数 ROUND(x,y) 返回参数x的四舍五入的有y位小数的值 RAND() 返回0到1内的随机值,可以通过提供一个参数(种子)使RAND( ...

最新文章

  1. 在Linux里设置环境变量的方法(export PATH)
  2. SpringBoot中在普通类里面加载Spring容器中的类
  3. PL/SQL两种case语句写法
  4. 一个偷偷修改工作目录的幕后黑手
  5. 醉了,RPC 超时设置也能引起线上事故!
  6. js encodeURIComponent 之php解码
  7. HAProxy介绍及配置文件详解
  8. 基于GDAL库,读取海洋风场数据(.nc格式)c++版
  9. SimpleDateFormat与线程安全
  10. Cover Protocol更新赔偿计划 新增三个新COVER代币获赔方
  11. 数据科学即将迎来“无代码”时代
  12. jumpserver 跳板机
  13. 易筋SpringBoot 2.1 | 第三十六篇:Spring Boot RestTemplate超时配置示例
  14. java爬虫 教程_Java爬虫其实也很简单,教你实用的入门级爬虫
  15. 数据分析----数据清洗和准备
  16. 微软商店的iTunes备份文件路径正确修改方法(2022.3.25)
  17. 学习笔记-Matlab二维绘图
  18. 非线性回归 python_回归算法之非线性回归
  19. 线性空间2--子空间
  20. Windows OpenGL 图像色调

热门文章

  1. python使用字典描述学生信息_一起学Python:字典介绍
  2. 图论算法及其matlab实现_BLDC有感FOC算法理论及其STM32软硬件实现
  3. Chromium内核原理之网络栈HTTP Cache
  4. ExcelPackage 读取、导出excel
  5. URL.createObjectURL图片预览
  6. sql 查询目标数据库中所有的表以其关键信息
  7. ARM学习篇 中断定时理解
  8. nopcommerce 二次开发
  9. UVa 10806 Dijkstra,Dijkstra(最小费用最大流)
  10. 每日长难句打卡Day22