AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 62746
Accepted
Paul
Paul
Asked: 2014-04-09 02:57:42 +0800 CST2014-04-09 02:57:42 +0800 CST 2014-04-09 02:57:42 +0800 CST

查找最后一个使用数据库的人的登录名或用户名

  • 772

老板要求提供数据库名称列表以及最后使用该数据库的人的大小和姓名。我找到了最后一次访问数据库的时间但由谁访问的资源。我将如何解决这个问题?

正在使用 SQL2008R2,到目前为止我有这个:

exec sp_MSForEachDB '
use ?
select ''?'', (SUM(df.size)*8)/1024 as ''Size (MB)''
from sys.database_files as df
'

答案的最后一个人方面模糊或松散是可以接受的。即只要是最近某个时候模糊地靠近它的人,那是“好的”。

sql-server sql-server-2008-r2
  • 1 1 个回答
  • 11908 Views

1 个回答

  • Voted
  1. Best Answer
    Aaron Bertrand
    2014-04-09T05:58:08+08:002014-04-09T05:58:08+08:00

    如果您的服务器已经运行了一段可靠的时间(例如至少一个业务周期),您可以使用诸如sys.dm_db_index_usage_stats.

    没有真正可靠的方法来判断谁最后“使用”了数据库。SQL Server 不会记录这些信息,除非他们做了一些实质性的事情(例如,您可能会看到用户在默认跟踪中创建或删除了一个对象,但这绝不会告诉您他们是最后一个访问数据库的人,或者如果那是他们最后一次访问数据库)。

    对于数据库文件大小,您根本不需要使用sp_MSforeachdb;无论如何你都不应该使用这种方法。原因如下:

    • https://sqlblog.org/2010/12/29/a-more-reliable-and-more-flexible-sp_msforeachdb

    • https://sqlblog.org/2010/02/08/bad-habits-to-kick-relying-on-undocumented-behavior

    • http://www.mssqltips.com/sqlservertip/2201/making-a-more-reliable-and-flexible-spmsforeachdb/

    在这种情况下,您无论如何都不需要遍历所有数据库;此信息在视图中复制master.sys.master_files。

    SELECT 
      d.name, 
      [Size (MB)] = SUM(mf.size)*8/1024
    FROM master.sys.databases AS d
    INNER JOIN master.sys.master_files AS mf
    ON d.database_id = mf.database_id
    GROUP BY d.name;
    

    如果您必须通过一堆不受master 支持的数据库做某事,我宁愿使用这种技术而不是使用sp_MSforeachdb:

    DECLARE @sql NVARCHAR(MAX) = N'';
    SELECT @sql += N'SELECT ''' + name + ''', (SUM(df.size)*8)/1024 as [Size (MB)]
      from ' + QUOTENAME(name) + '.sys.database_files as df;';
    EXEC sp_executesql @sql;
    

    (顺便说一句,不要'single quotes'用来分隔别名,请使用[square brackets]。前者在某些形式中已被弃用 - 请参阅此处和此处- 并且无论如何都会使您的别名看起来像字符串文字。)

    对于“何时”部分,请从我的回答中复制:

    SQL Server 并没有真正按照您想要的方式跟踪数据库访问,至少是向后跟踪(您可以设置诸如服务器端跟踪、扩展事件、审计等之类的东西。向前)。

    您可以使用一件大致的事情:跟踪索引使用情况和过程/触发器/查询统计信息的 DMV。例如:

    ;WITH d AS
    (
      SELECT d = database_id, name FROM sys.databases
      WHERE state = 0 AND database_id BETWEEN 5 AND 32766
    ),
    index_usage(d,lsk,lsc,llk,lupd) AS
    (
      SELECT database_id, MAX(last_user_seek), MAX(last_user_scan),
        MAX(last_user_lookup), MAX(last_user_update)
      FROM sys.dm_db_index_usage_stats
      WHERE database_id BETWEEN 5 AND 32766
      GROUP BY database_id
    ),
    proc_stats(d,lproc) AS
    (
      SELECT database_id, MAX(last_execution_time) 
        FROM sys.dm_exec_procedure_stats
        WHERE database_id BETWEEN 5 AND 32766
        GROUP BY database_id
    ),
    trig_stats(d,ltrig) AS
    (
      SELECT database_id, MAX(last_execution_time)
        FROM sys.dm_exec_trigger_stats
        WHERE database_id BETWEEN 5 AND 32766
        GROUP BY database_id
    ),
    query_stats(d,lquery) AS
    (
      SELECT t.[dbid], MAX(s.last_execution_time) 
        FROM sys.dm_exec_query_stats AS s
        CROSS APPLY sys.dm_exec_sql_text(s.plan_handle) AS t
        WHERE t.[dbid] BETWEEN 5 AND 32766
        GROUP BY t.[dbid]
    )
    SELECT d.name,i.lsk,i.lsc,i.llk,i.lupd,p.lproc,t.ltrig,q.lquery
    FROM d LEFT OUTER JOIN index_usage AS i ON d.d = i.d
    LEFT OUTER JOIN proc_stats  AS p ON d.d = p.d
    LEFT OUTER JOIN trig_stats  AS t ON d.d = t.d
    LEFT OUTER JOIN query_stats AS q ON d.d = q.d;
    

    请注意,这些统计信息并不完全可靠,因为您可能没有任何存储过程,并且在其中找到的查询sys.dm_exec_query_stats可能引用多个数据库,并且可能永远不会反映您关注的那个。

    此外,它们会在 SQL Server 重新启动、数据库分离/附加或恢复,或者数据库自动关闭时重置,并且在某些情况下还可能取决于仍在缓存中的计划(另一个数据库可以在几分钟内完全接管)。因此,如果您回顾过去,除非您知道在整个业务周期中没有发生这些事情,否则我不会仅依靠这些数字来确定是否使用了数据库(也可能有自动化流程正在数据库看起来是最新的,即使您不关心删除数据库时这些自动化过程会失败)。

    另一个注意事项是在索引使用视图中可能无法跟踪某些索引访问;例如,在添加内存优化表的 SQL Server 2014 中,不会以这种方式捕获针对这些哈希索引的活动(并且您认为将捕获活动的视图,例如sys.dm_db_xtp_hash_index_stats,不包含任何日期/时间列)。如果您使用 SQL Server 2014 和内存中 OLTP(“Hekaton”),您可能需要添加一些研究来涵盖这些对象(以防它们是数据库中唯一被引用的对象)。

    还有一点需要注意的是,捕获的查询sys.dm_exec_query_stats可能是误报。例如,如果您的数据库有filestream/ filetable,您将看到系统偶尔运行这些查询:

    select table_id, item_guid, oplsn_fseqno, oplsn_bOffset, oplsn_slotid
    from [database].[sys].[filetable_updates_<some_id>] with (readpast) order by table_id
    

    因此,您可能希望在上述查询中添加额外的过滤来过滤掉那些(只要过滤器不会意外过滤掉您关心的查询)。这可能是对该派生表的安全补充:

    AND t.[text] NOT LIKE N'%oplsn_fseqno%'
    

    最后,在开发环境中最安全的做法是将不确定的数据库离线一周。如果没有人抱怨,支持他们,然后放弃他们。如果某人需要超过一周的时间才能注意到他们失踪了,您可以随时恢复他们(那里或其他地方)。

    我也写过一些关于这个的博客:

    • https://sqlblog.org/2008/05/06/when-was-my-database-table-last-accessed
    • 4

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve