用于从表中选择特定列的SQL查询优化

时间:2014-08-29 20:41:49

标签: sql oracle optimization

我正在尝试选择所有包含OWNERID或L1ID或L1列的表,但不包含以下任何列:HID,DHID,SPHID,SPHID,LINKHID,NODEID和SITEID。

以下是我的SQL查询。这需要很长时间。你能给我一个更好的解决方案或优化这个查询。

SELECT 
      TABLE_NAME 
   FROM 
      USER_TABLES
   WHERE 
         TABLE_NAME NOT IN (
            SELECT TABLE_NAME 
               FROM USER_TAB_COLUMNS 
               WHERE COLUMN_NAME IN('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID')
               GROUP BY TABLE_NAME 
               HAVING COUNT(*) = 1)
      AND TABLE_NAME IN (
            SELECT TABLE_NAME 
               FROM USER_TAB_COLUMNS 
               WHERE COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1')
               GROUP BY TABLE_NAME 
               HAVING COUNT(*) = 1)

请不要将此标记为重复。我已经尝试了其他解决方案,他们似乎没有为我锻炼

3 个答案:

答案 0 :(得分:1)

尝试不存在/存在。只要您不需要从辅助表中选择值,这比IN快得多,尤其不是IN。基本原因是,只要匹配,评估就完成了。

SELECT 
TABLE_NAME 
FROM USER_TABLES
WHERE NOT EXISTS
(select 1
  FROM USER_TAB_COLUMNS
  WHERE COLUMN_NAME IN('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID')
  AND USER_TABLES.TABLE_NAME = USER_TAB_COLUMNS.TABLE_NAME
)
and EXISTS (
  SELECT 1 
  FROM USER_TAB_COLUMNS 
  WHERE COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1')
  AND USER_TABLES.TABLE_NAME = USER_TAB_COLUMNS.TABLE_NAME
)

但是,我不完全确定您的COUNT(*)= 1表示什么。只有一个OWNERID或L1ID或L1,但不是说同一个表中的L1ID和L1?

如果您只关心是否存在一个或多个条件列,即我如何理解您的英语问题,那么我的代码将会有效。如果您只需要其中一个,则需要进行不同的查询。

答案 1 :(得分:0)

尝试这样做:

SELECT TABLE_NAME 
FROM USER_TAB_COLUMNS
 GROUP BY TABLE_NAME
HAVING SUM(CASE WHEN COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1') THEN 1 ELSE 0 END) = 1 AND
       SUM(CASE WHEN COLUMN_NAME IN ('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID') THEN 1 ELSE 0 END) = 0;

答案 2 :(得分:0)

With exclude AS (
  select TABLE_NAME
  FROM USER_TAB_COLUMNS
  WHERE COLUMN_NAME IN('HID', 'DHID', 'SPHID', 'LINKID', 'NODEID', 'SITEID')
  GROUP BY TABLE_NAME
)
, preInclude AS (
  SELECT TABLE_NAME
  FROM USER_TAB_COLUMNS 
  WHERE COLUMN_NAME IN ('OWNERID', 'L1ID', 'L1')
  GROUP BY TABLE_NAME
 ) 
, Include AS (
  SELECT preInclude.TABLE_NAME
  FROM preInclude
  LEFT JOIN exclude ON preIncude.TABLE_NAME = exclude.TABLE_NAME
  WHERE exclude.TABLE_NAME is NULL
)

SELECT * 
FROM Include