51

In SQL Server there is two schemas for metadata:

  • INFORMATION_SCHEMA
  • SYS

I have heard that INFORMATION_SCHEMA tables are based on ANSI standard. When developing e.g. stored procedures, should it be wise to use INFORMATION_SCHEMA tables over sys tables?

juur
  • 5,633
  • 10
  • 32
  • 36
  • The Resource database is a read-only database that contains all the system objects that are included with SQL Server. SQL Server system objects, such as sys.objects, are physically persisted in the Resource database, but they logically appear in the sys schema of every database – Channa May 13 '19 at 05:37

4 Answers4

33

Unless you are writing an application which you know for a fact will need to be portable or you only want quite basic information I would just default to using the proprietary SQL Server system views to begin with.

The Information_Schema views only show objects that are compatible with the SQL-92 standard. This means there is no information schema view for even quite basic constructs such as indexes (These are not defined in the standard and are left as implementation details.) Let alone any SQL Server proprietary features.

Additionally it is not quite the panacea for portability that one may assume. Implementations do still differ between systems. Oracle does not implement it "out of the box" at all and the MySql docs say:

Users of SQL Server 2000 (which also follows the standard) may notice a strong similarity. However, MySQL has omitted many columns that are not relevant for our implementation, and added columns that are MySQL-specific. One such column is the ENGINE column in the INFORMATION_SCHEMA.TABLES table.

Even for bread and butter SQL constructs such as foreign key constraints the Information_Schema views can be dramatically less efficient to work with than the sys. views as they do not expose object ids that would allow efficient querying.

e.g. See the question SQL query slow-down from 1 second to 11 minutes - why? and execution plans.

INFORMATION_SCHEMA

Plan

sys

Plan

Community
  • 1
  • 1
Martin Smith
  • 438,706
  • 87
  • 741
  • 845
  • 1
    "...you know for a fact will need to be portable..." -- remember that each new version of SQL Server is a port. Future-proofing is a judgement call e.g. are the SQL Server team more likely to ditch the Standard Information_Schema VIEWs or revise their proprietary sys tables? – onedaywhen Sep 07 '10 at 09:49
  • 1
    That is the big question, indeed. But MS does promise to maintain the sys views as backward compatible if you use column names... they reserve the right to add columns. Both sys & information_schema are expected to protect you from changes to the underlying system tables in a new version of SQL Server. – Mike M May 06 '14 at 20:07
31

I would always try to use the Information_schema views over querying the sys schema directly.

The Views are ISO compliant so in theory you should be able to easily migrate any queries across different RDBMS.

However, there have been some cases where the information that I need is just not available in a view.

I've provided some links with further information on the views and querying a SQL Server Catalog.

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

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

codingbadger
  • 42,678
  • 13
  • 95
  • 110
  • 19
    Yes, I agree - as long as you need to / want to be "portable" between databases. If you do 100% of SQL Server work, I typically use the "sys." catalog views, since those are more complete, more concise, and better organized (in my opinion) - full well knowing those queries won't work on DB2 or MySQL... – marc_s Sep 06 '10 at 18:46
  • @Marc_s - Yes i should have really made a point of that. If you are **really** sure that it doesn't need to be migrated anywhere else then you'll be fine using the `sys` schema. Nice comment – codingbadger Sep 06 '10 at 18:57
10

INFORMATION_SCHEMA is more suitable for external code that may need to interface with a variety of databases. Once you start programming in the database, portability kind of goes out the window. If you are writing stored procedures, that tells me you have committed to a particular database platform (for better or for worse). If you have committed to SQL Server, then by all means, use the sys views.

Peter Radocchia
  • 10,710
  • 2
  • 34
  • 56
1

I won't repeat some of the other answers but add a performance perspective. information_schema views, as Martin Smith mentions in his answer, are not the most efficient source of this information since they have to expose standard columns that have to be collected from multiple underlying sources. sys views can be more efficient from that perspective, so if you have high performance requirements, and don't have to worry about portability, you should probably go with sys views.

For example, the first query below uses information_schema.tables to check if a table exists. The second one uses sys.tables to do the same thing.

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';

When you view the IO for these, the first query has 4 logical reads to sysschobjs and sysclsobjs, while the second one has none. Also the first one does two non-clustered index seeks and a key lookup while the second one only does a single clustered index seek. First one costs ~3x more than the second one according to query plans. If you have to do this lots of times in a large system, say for deployment time, this could add up and cause performance problems. But this really only applies to heavily loaded systems. Most IT line of business systems don't have these levels of performance issues.

Again, the overall cost of these are very small individually when compared to other queries in most systems but if your system has a lot of this type of activity, it could add up.

Tombala
  • 1,660
  • 9
  • 11