【问题标题】:Optimize long query to find database schema with foreign keys and tables优化长查询以查找具有外键和表的数据库模式
【发布时间】:2021-11-05 20:19:30
【问题描述】:

我正在编写一个查询来获取数据库中的所有表及其属性,以及每个引用的外键和表。我有以下查询,但需要 60 分钟才能完成。不知道我做错了什么?

SELECT 
    ist.table_name,
    isc.column_name,
    data_type,
    character_maximum_length,
    Columnproperty(Object_id(isc.table_name), 
    isc.column_name, 'IsIdentity') AS identityFlag,
    is_nullable,
    character_maximum_length,
    numeric_scale,
    (SELECT 1
     FROM information_schema.table_constraints AS C
     JOIN information_schema.key_column_usage AS K ON C.table_name = K.table_name
                                                   AND C.constraint_catalog = K.constraint_catalog
                                                   AND C.constraint_schema = K.constraint_schema
                                                   AND C.constraint_name = K.constraint_name
     WHERE C.constraint_type = 'PRIMARY KEY'
       AND C.table_name = isc.table_name
       AND K.column_name = isc.column_name) AS primarykey,
    (SELECT TOP 1 1
     FROM information_schema.table_constraints AS C
     JOIN information_schema.key_column_usage AS K ON C.table_name = K.table_name
                                                   AND C.constraint_catalog = K.constraint_catalog
                                                   AND C.constraint_schema = K.constraint_schema
                                                   AND C.constraint_name = K.constraint_name
     WHERE C.constraint_type = 'FOREIGN KEY'
       AND C.table_name = isc.table_name
       AND K.column_name = isc.column_name) AS foreignKey,
    a.parenttablename AS foreignTableName,   
    a.colname AS foreignColumnName
FROM   
    information_schema.tables ist
INNER JOIN 
    information_schema.columns isc ON ist.table_name = isc.table_name
LEFT OUTER JOIN 
    (SELECT 
         t.NAME AS parentTableName,
         Object_name(f.parent_object_id) TableName,
         Col_name(fc.parent_object_id, fc.parent_column_id) ColName
     FROM   
         sys.foreign_keys AS f
     INNER JOIN 
         sys.foreign_key_columns AS fc ON f.object_id = fc.constraint_object_id
     INNER JOIN 
         sys.tables t ON t.object_id = fc.referenced_object_id) a ON a.tablename = ist.table_name
                                                                  AND a.colname = isc.column_name 

查找外部表名需要时间。获取数据库表模式的最佳方法是什么

【问题讨论】:

  • 此查询为我返回 14k 行并在 2 秒内运行。
  • @Stu 谢谢,我运行这个需要 30 分钟。但我有 100,000 条记录
  • 嗯,它已经从 60 分钟缩短到 30 分钟,所以事情看起来很有希望!检查执行计划以查看时间消耗的位置。
  • primarykeyforeignKey 子查询分别执行 100,000 次 - 每行一次。想一想如何将它们变成基于集合的连接,每个连接只执行一次。
  • @AlwaysLearning 我明白了,你能帮我做基于集合的连接吗?

标签: sql-server database tsql


【解决方案1】:
  • 首先,您应该坚持使用sys 架构,因为这些目录视图更高效,而INFORMATION_SCHEMA 只是为了兼容
  • 您过于复杂了。您不需要两次查询外键,您可以通过检查NULL来检查LEFT JOIN是否成功
SELECT 
    t.name AS table_name,
    c.name AS column_name,
    typ.name AS data_type,
    c.max_length,
    c.is_identity AS identityFlag,
    c.is_nullable,
    c.precision,
    c.scale,
    CASE WHEN EXISTS (SELECT 1
        FROM sys.indexes AS i
        JOIN sys.index_columns AS ic
              ON ic.object_id = i.object_id
             AND ic.index_id = i.index_id
        WHERE i.object_id = t.object_id
          AND ic.column_id = c.column_id
        ) THEN 1 ELSE 0 END AS primarykey,
    CASE WHEN t_f.name IS NOT NULL THEN 1 ELSE 0 END AS foreignKey,
    t_f.name AS foreignTableName,   
    c_f.name AS foreignColumnName
FROM   
    sys.tables t
INNER JOIN 
    sys.columns c ON c.object_id = t.object_id
INNER JOIN
    sys.types typ ON typ.user_type_id = c.user_type_id
LEFT OUTER JOIN
    sys.foreign_key_columns AS fc
    INNER JOIN 
        sys.tables t_f ON t_f.object_id = fc.referenced_object_id
    INNER JOIN
        sys.columns c_f ON c_f.object_id = t_f.object_id
                       AND c_f.column_id = fc.referenced_column_id
  ON fc.parent_object_id = t.object_id
  AND fc.parent_column_id = c.column_id;

【讨论】:

    猜你喜欢
    • 2013-02-02
    • 2020-08-26
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 2011-12-07
    • 2018-09-04
    相关资源
    最近更新 更多