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 表吗?的主要内容,如果未能解决你的问题,请参考以下文章
MS Access 2016 在某个链接的 SQL Server 表上崩溃
如何在 SQL Server 2012 中创建的临时表上查找索引列表