简体   繁体   English

连接性能较差的SQL查询

[英]SQL query with poor join performance

I'm experiencing very poor performance in a query I've written for Oracle 12c. 我在为Oracle 12c编写的查询中遇到了非常糟糕的性能。 It's probably related to my inefficient use of joins and was hoping someone could help me out with where I'm going wrong. 这可能与我对连接的低效使用有关,并希望有人可以帮我解决我出错的地方。 The query I have is currently taking over a minute to run . 我的查询目前正在运行一分钟

I'm am trying to return the table and column names where: 我正在尝试返回表和列名称:

  • The column belongs to a Primary Key 该列属于主键
  • The column type is Number 列类型为Number
  • The owner of the table is MY_OWNER 表的所​​有者是MY_OWNER
  • The Primary Key is a single column constraint 主键是单列约束

Currently my query looks as follows 目前我的查询如下

SELECT consCols.table_name, consCols.column_name 
FROM all_cons_columns consCols
INNER JOIN all_constraints cons 
  ON cons.constraint_name = consCols.constraint_name
INNER JOIN all_tab_columns cols 
  ON consCols.table_name = cols.table_name AND consCols.column_name = cols.column_name
WHERE cons.constraint_type = 'P' 
AND cons.owner = 'MY_OWNER'
AND cols.data_type = 'NUMBER'
AND consCols.table_name IN(
  SELECT consCols2.table_name 
  FROM all_cons_columns consCols2
  INNER JOIN all_constraints cons2 
    ON cons2.constraint_name = consCols2.constraint_name
  WHERE cons2.constraint_type = 'P' 
  AND cons2.owner = 'MY_OWNER' 
  GROUP BY consCols2.table_name
  HAVING COUNT(consCols2.table_name) = 1
);

Thank you for any help you can give me. 谢谢你能给我的任何帮助。

Would using analytic functions speed the query? 使用分析函数会加快查询速度吗?

SELECT table_name, column_name
FROM (SELECT consCols.table_name, consCols.column_name, cols.data_type,
             COUNT(*) OVER (PARTITION BY consCols.table_name) as cnt
      FROM all_cons_columns consCols INNER JOIN
           all_constraints cons 
           ON cons.constraint_name = consCols.constraint_name INNER JOIN
           all_tab_columns cols 
           ON consCols.table_name = cols.table_name AND consCols.column_name = cols.column_name
      WHERE cons.constraint_type = 'P' AND
            cons.owner = 'MY_OWNER'
     ) tc               
WHERE data_type = 'NUMBER' AND cnt = 1;

Or even aggregation? 甚至聚合?

  SELECT consCols.table_name, consCols.column_name
  FROM all_cons_columns consCols INNER JOIN
       all_constraints cons 
       ON cons.constraint_name = consCols.constraint_name INNER JOIN
       all_tab_columns cols 
       ON consCols.table_name = cols.table_name AND consCols.column_name = cols.column_name
  WHERE cons.constraint_type = 'P' AND
        cons.owner = 'MY_OWNER'
  GROUP BY consCols.table_name, consCols.column_name
  HAVING COUNT(*) = 1 AND
         MAX(cols.data_type) = 'NUMBER';

Here is a third option: 这是第三种选择:

  SELECT consCols.table_name, consCols.column_name
  FROM all_cons_columns consCols INNER JOIN
       all_constraints cons 
       ON cons.constraint_name = consCols.constraint_name INNER JOIN
       all_tab_columns cols 
       ON consCols.table_name = cols.table_name AND consCols.column_name = cols.column_name
  WHERE cons.constraint_type = 'P' AND
        cons.owner = 'MY_OWNER' AND
        cols.data_type = 'NUMBER' AND
        NOT EXISTS (SELECT 1
                    FROM all_cons_columns acc
                    WHERE acc.constraint_name = consCols.constraint_name AND
                          acc.table_name = consCols.table_name AND
                          acc.column_name <> consCols.column_name
                   );

This eliminates the aggregation and the lookup should be relatively fast. 这消除了聚合,查找应该相对较快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM