SQL Server:我应该在 sys 表上使用 information_schema 表吗?

Posted

技术标签:

【中文标题】SQL Server:我应该在 sys 表上使用 information_schema 表吗?【英文标题】:SQL Server: should I use information_schema tables over sys tables? 【发布时间】:2011-04-08 21:25:57 【问题描述】:

在 SQL Server 中,元数据有两种模式:

INFORMATION_SCHEMA 系统

我听说INFORMATION_SCHEMA 表是基于 ANSI 标准的。开发时,例如存储过程,使用INFORMATION_SCHEMA 表而不是sys 表是否明智?

【问题讨论】:

资源数据库是一个只读数据库,其中包含 SQL Server 附带的所有系统对象。 SQL Server 系统对象,例如 sys.objects,物理上持久化在 Resource 数据库中,但它们在逻辑上出现在每个数据库的 sys 架构中 【参考方案1】:

除非您正在编写一个您知道需要可移植的应用程序,或者您只需要非常基本的信息,否则我会默认使用专有的 SQL Server 系统视图开始。

Information_Schema 视图仅显示与 SQL-92 标准兼容的对象。这意味着即使是非常基本的结构(例如索引)也没有信息架构视图(这些结构没有在标准中定义,而是作为实现细节保留。)更不用说任何 SQL Server 专有功能了。

此外,它并不是人们可能认为的便携性的灵丹妙药。系统之间的实现仍然不同。 Oracle 根本没有“开箱即用”地实现它,the mysql docs 说:

SQL Server 2000(也遵循该标准)的用户可能会注意到 强烈的相似性。但是,MySQL 省略了许多列 与我们的实施无关,并添加了 MySQL 特定的。此类列之一是 INFORMATION_SCHEMA.TABLES 表。

即使对于诸如外键约束之类的基本 SQL 构造,Information_Schema 视图的使用效率也可能远低于 sys. 视图,因为它们不会公开允许高效查询的对象 ID。

例如请参阅问题SQL query slow-down from 1 second to 11 minutes - why? 和执行计划。

INFORMATION_SCHEMA

系统

【讨论】:

"...您知道事实上需要可移植..." -- 请记住,每个新版本的 SQL Server 都是一个端口。面向未来是一种判断调用,例如SQL Server 团队是否更有可能放弃标准 Information_Schema VIEW 或修改其专有的 sys 表? 这确实是个大问题。但是,如果您使用列名,MS 确实承诺将 sys 视图保持为向后兼容......他们保留添加列的权利。 sys 和 information_schema 都有望保护您免受新版本 SQL Server 中基础系统表的更改。【参考方案2】:

我总是尝试使用Information_schema 视图而不是直接查询sys 架构。

视图符合 ISO 标准,因此理论上您应该能够轻松地跨不同 RDBMS 迁移任何查询。

但是,在某些情况下,我需要的信息在视图中不可用。

我提供了一些链接,其中包含有关视图和查询 SQL Server 目录的更多信息。

http://msdn.microsoft.com/en-us/library/ms186778.aspx

http://msdn.microsoft.com/en-us/library/ms189082.aspx

【讨论】:

是的,我同意——只要您需要/想要在数据库之间“可移植”。如果您完成 100% 的 SQL Server 工作,我通常使用“sys.”。目录视图,因为它们更完整、更简洁、组织得更好(在我看来)——完全知道这些查询在 DB2 或 MySQL 上不起作用...... @Marc_s - 是的,我真的应该指出这一点。如果您真的确定它不需要迁移到其他任何地方,那么使用sys 架构就可以了。不错的评论【参考方案3】:

INFORMATION_SCHEMA更适合可能需要与各种数据库接口的外部代码。一旦您开始in 对数据库进行编程,可移植性就会消失。如果您正在编写存储过程,这告诉我您已经致力于特定的数据库平台(无论好坏)。如果您已承诺使用 SQL Server,那么请务必使用 sys 视图。

【讨论】:

【参考方案4】:

我不会重复其他一些答案,而是添加一个性能观点。正如 Martin Smith 在他的回答中提到的,information_schema 视图并不是最有效的信息来源,因为它们必须公开必须从多个基础来源收集的标准列。从这个角度来看,sys 视图可能更有效,因此如果您有很高的性能要求,并且不必担心可移植性,您可能应该使用 sys 视图。

例如,下面的第一个查询使用 information_schema.tables 来检查表是否存在。第二个使用 sys.tables 做同样的事情。

if exists (select * from information_schema.tables where table_schema = 'dbo' and table_name = 'MyTable')
    print '75% cost';

if exists (select * from sys.tables where object_id = object_id('dbo.MyTable'))
    print '25% cost';

当您查看这些 IO 时,第一个查询对 sysschobjs 和 sysclsobjs 有 4 次逻辑读取,而第二个没有。第一个也执行两个非聚集索引查找和一个键查找,而第二个只执行单个聚集索引查找。根据查询计划,第一个成本比第二个高约 3 倍。如果您必须在大型系统中多次执行此操作,例如部署时间,这可能会累加并导致性能问题。但这实际上只适用于负载较重的系统。大多数 IT 业务线系统都没有这些级别的性能问题。

同样,与大多数系统中的其他查询相比,这些单独的总体成本非常小,但如果您的系统有很多此类活动,则可能会累加。

【讨论】:

以上是关于SQL Server:我应该在 sys 表上使用 information_schema 表吗?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 在事实表上插入查询

如何在 SQL Server 中查找上次修改表的人?

MS Access 2016 在某个链接的 SQL Server 表上崩溃

如何在 SQL Server 2012 中创建的临时表上查找索引列表

CONTAINS 谓词在 SQL Server 2008 中也不返回它应该返回的所有行

SQL Server Union 全部在 2 个表上,除此之外