【问题标题】:Table Key Gathering from Information Schema in MySQL从 MySQL 中的信息模式收集表键
【发布时间】:2014-02-04 02:41:15
【问题描述】:

在 MySQL 中,我尝试使用 Information Schema 来收集有关我的表的数据。我的目标是在一个查询中选择数据并将其直接插入到另一个表中以供将来分析和处理。

这是我写的一个查询。不幸的是,大多数时候 pk_length(主键中的列数)不正确,有时表上的键数也是错误的。

  SELECT
    t.table_schema,
    t.table_name,
    SUM(k.constraint_name="PRIMARY") as pk_length,
    count(distinct s.index_name) as key_count,
    t.table_rows
  FROM tables t, statistics s, key_column_usage k
    WHERE  t.table_name = s.table_name 
    AND t.table_schema = s.table_schema
    AND t.table_name = k.table_name
    AND t.table_schema = k.table_schema
  GROUP BY t.table_schema, t.table_name;

我做错了什么导致这两个字段的数据不正确?

编辑:这是使用子查询的固定查询。

  SELECT
    t.table_schema,
    t.table_name,
    k.pk_length,
    count(distinct s.index_name) as key_count,
    t.table_rows
  FROM tables t,
    statistics s,
    (SELECT table_schema, table_name, count(*) as "pk_length" 
      FROM key_column_usage group by table_schema, table_name) as k
  WHERE  t.table_name = s.table_name 
    AND t.table_schema = s.table_schema
    AND t.table_name = k.table_name
    AND t.table_schema = k.table_schema
  GROUP BY t.table_schema, t.table_name
  LIMIT 20;

【问题讨论】:

    标签: mysql information-schema


    【解决方案1】:

    记住:

    • 当您根据非唯一值连接两个表时,最终会得到包含匹配字段的行的所有可能组合。

    • table_nametable_schema 不是 key_column_usage 中的唯一值。

    因此,在key_column_usage 中针对给定表存在多行的情况下,您最终会得到来自statistics 的相应行的多个副本。这弄乱了你的pk_length

    您很可能需要将其拆分为两个单独的查询:一个用于pk_length,另一个用于key_count

    【讨论】:

    • 我正在考虑拆分它,但作为INSERT INTO <aggregate_table> SELECT FROM,我需要将所有选择放在一个查询中。不过,我可以进行多次插入然后聚合它们。
    • 那么,使用子查询怎么样?
    • 子查询很完美。我已将结果查询放入问题中。
    【解决方案2】:

    更新

    SELECT
        t.table_schema,
        t.table_name,
        t.table_rows,
        SUM(s.index_name = 'PRIMARY') AS pk_length,
        COUNT(DISTINCT s.index_name) AS key_count
    FROM
        tables t, statistics s
    WHERE
        t.table_name = s.table_name 
        AND t.table_schema = s.table_schema
    GROUP BY
        t.table_schema, t.table_name;
    

    第一种方法(错误答案)

    这个怎么样?

    SELECT
        t.table_schema,
        t.table_name,
        t.table_rows,
        SUM(s.index_name = 'PRIMARY') AS pk_length,
        SUM(s.index_name != 'PRIMARY') AS key_count
    FROM
        tables t, statistics s
    WHERE
        t.table_name = s.table_name 
        AND t.table_schema = s.table_schema
    GROUP BY
        t.table_schema, t.table_name;
    

    【讨论】:

    • pk_length 来自不同的表。此外,这个查询会给我非主索引中的列数,而不是非主索引的数量。
    • @Jericon 好的。我已经更新了我的答案。我误解了key_count。但是,pk_length 令人困惑。我认为 pk_length 可以算作我尝试仅使用 2 个表加入。
    • @Jericon 我目前已经阅读了您使用子查询修改后的查询。与您的查询相比,我更新的查询返回相同的结果,并且使用两个表并且比您的查询更快。我不明白为什么我的回答被否决了。
    • @Jericon And...我认为您的子查询不会返回没有 PK 的表。请考虑LEFT JOIN (subquery) k
    • @Jericon 另一个问题。 key_column_usage 不仅包含 PK,还包含 FK。不知道你是不是真的要把FK算作PK。
    猜你喜欢
    • 2013-07-13
    • 2022-06-29
    • 1970-01-01
    • 1970-01-01
    • 2021-02-28
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多