Oracle 优化对两个值都匹配的记录的查询

Oracle 优化对两个值都匹配的记录的查询,oracle,optimization,Oracle,Optimization,我正在尝试优化Oracle查询。现在它运行得相当慢,因为该表有约100万条记录。我有两个表,item\u location表和关税表。项目位置记录有一个双键,项目编号和项目位置。关税记录用一个键关税编码存储,该键是一个随机的三位标识符,带有字段进口关税和出口关税。项目\关税\代码是项目的关税记录的外键 这里有一个简单的例子 我正在尝试查找项目编号,其所在位置的出口关税匹配两个值(包括两个值) 例如,如果我想查找出口关税同时等于“1111111111”和“22222”的项目,它将返回“12345”

我正在尝试优化Oracle查询。现在它运行得相当慢,因为该表有约100万条记录。我有两个表,
item\u location
表和
关税
表。
项目位置
记录有一个双键,
项目编号
项目位置
关税
记录用一个键
关税编码
存储,该键是一个随机的三位标识符,带有字段
进口关税
出口关税
项目\关税\代码
是项目的
关税
记录的外键

这里有一个简单的例子

我正在尝试查找
项目编号
,其所在位置的
出口关税
匹配两个值(包括两个值)

例如,如果我想查找
出口关税
同时等于“1111111111”和“22222”的项目,它将返回“12345”,因为这些记录在数据库中:

  item_no  |  item_loc  |  export_tariff
----------------------------------------
  12345    |  B1        |  1111111111
  12345    |  B2        |  2222222222
但它不应该找到“67890”,因为这个记录:

  item_no  |  item_loc  |  export_tariff
----------------------------------------
  67890    |  B1        |  1111111111
因为它没有出口关税


我已经在中添加了到目前为止一直在使用的查询。

如果您对出口关税进行了索引,也许您可以进行两次索引查找,并将结果合并以查找感兴趣的项目

SELECT DISTINCT a.item_no, a.item_loc
  FROM ( SELECT item_no, item_loc
           FROM item_location
           WHERE export_tariff = '1111111111'
       ) a
      ,( SELECT item_no, item_loc
           FROM item_location
           WHERE export_tariff = '2222222222'
       ) b
  WHERE a.item_no = b.item_no

如果您对出口关税进行了索引,那么您可以进行两次索引查找,并将结果合并以查找感兴趣的项目

SELECT DISTINCT a.item_no, a.item_loc
  FROM ( SELECT item_no, item_loc
           FROM item_location
           WHERE export_tariff = '1111111111'
       ) a
      ,( SELECT item_no, item_loc
           FROM item_location
           WHERE export_tariff = '2222222222'
       ) b
  WHERE a.item_no = b.item_no

如果您不能使用临时表,Oracle有WITH子句,它的使用方式与此基本相同:

WITH t as (SELECT tariff_code FROM tariffs WHERE 
    (export_tariff LIKE '3916906000%' OR export_tariff LIKE '39191080%'))
SELECT t1.item_no FROM
(SELECT * FROM item_location il, t WHERE il.item_tariff_code = t.tariff_code) t1,
(SELECT * FROM item_location il, t WHERE il.item_tariff_code = t.tariff_code) t2
WHERE t1.item_no = t2.item_no AND t1.item_tariff_code <> t2.item_tariff_code

如果您不能使用临时表,请参见

,Oracle有WITH子句,其使用方式与此基本相同:

WITH t as (SELECT tariff_code FROM tariffs WHERE 
    (export_tariff LIKE '3916906000%' OR export_tariff LIKE '39191080%'))
SELECT t1.item_no FROM
(SELECT * FROM item_location il, t WHERE il.item_tariff_code = t.tariff_code) t1,
(SELECT * FROM item_location il, t WHERE il.item_tariff_code = t.tariff_code) t2
WHERE t1.item_no = t2.item_no AND t1.item_tariff_code <> t2.item_tariff_code

请参见

以下内容:

SELECT
  FIRST.ITEM_NO, FIRST.ITEM_LOC, FIRST.ITEM_TARIFF_CODE, FIRST.EXPORT_TARIFF, SECOND.ITEM_TARIFF_CODE, SECOND.EXPORT_TARIFF
FROM (
   -- using a simple inner join of item_location and tariffs,
   -- create a right outer join by joining the inner join on itself 
    SELECT A.ITEM_NO, A.ITEM_LOC, A.ITEM_TARIFF_CODE, B.EXPORT_TARIFF
    FROM
      ITEM_LOCATION A INNER JOIN TARIFFS B ON (A.ITEM_TARIFF_CODE = B.TARIFF_CODE)
    ) FIRST
  RIGHT OUTER JOIN (
    -- SAME INNER JOIN
    SELECT A.ITEM_NO, A.ITEM_LOC, A.ITEM_TARIFF_CODE, B.EXPORT_TARIFF
    FROM
      ITEM_LOCATION A INNER JOIN TARIFFS B ON (A.ITEM_TARIFF_CODE = B.TARIFF_CODE)
    ) SECOND
  ON (FIRST.ITEM_NO = SECOND.ITEM_NO)
WHERE
  -- select the export tariffs you want
  FIRST.EXPORT_TARIFF = '6808417805' AND SECOND.EXPORT_TARIFF = '6046232842'
;

类似于以下的方法应该可以工作:

SELECT
  FIRST.ITEM_NO, FIRST.ITEM_LOC, FIRST.ITEM_TARIFF_CODE, FIRST.EXPORT_TARIFF, SECOND.ITEM_TARIFF_CODE, SECOND.EXPORT_TARIFF
FROM (
   -- using a simple inner join of item_location and tariffs,
   -- create a right outer join by joining the inner join on itself 
    SELECT A.ITEM_NO, A.ITEM_LOC, A.ITEM_TARIFF_CODE, B.EXPORT_TARIFF
    FROM
      ITEM_LOCATION A INNER JOIN TARIFFS B ON (A.ITEM_TARIFF_CODE = B.TARIFF_CODE)
    ) FIRST
  RIGHT OUTER JOIN (
    -- SAME INNER JOIN
    SELECT A.ITEM_NO, A.ITEM_LOC, A.ITEM_TARIFF_CODE, B.EXPORT_TARIFF
    FROM
      ITEM_LOCATION A INNER JOIN TARIFFS B ON (A.ITEM_TARIFF_CODE = B.TARIFF_CODE)
    ) SECOND
  ON (FIRST.ITEM_NO = SECOND.ITEM_NO)
WHERE
  -- select the export tariffs you want
  FIRST.EXPORT_TARIFF = '6808417805' AND SECOND.EXPORT_TARIFF = '6046232842'
;
像这样的

SELECT 
  l1.item_no
FROM 
  item_location AS l1
CROSS JOIN
  item_location AS l2 ON l2.item_no = l1.item_no
JOIN 
  tariffs AS t1 ON l1.item_tariff_code = t1.tariff_code
JOIN
  tariffs AS t2 ON l2.item_tariff_code = t2.tariff_code
WHERE
  t1.export_tariff LIKE '1111111111' 
  AND
  t2.export_tariff LIKE '2222222222' 
像这样的

SELECT 
  l1.item_no
FROM 
  item_location AS l1
CROSS JOIN
  item_location AS l2 ON l2.item_no = l1.item_no
JOIN 
  tariffs AS t1 ON l1.item_tariff_code = t1.tariff_code
JOIN
  tariffs AS t2 ON l2.item_tariff_code = t2.tariff_code
WHERE
  t1.export_tariff LIKE '1111111111' 
  AND
  t2.export_tariff LIKE '2222222222' 

有趣的解决方案,但不幸的是,我在一个非常规范的环境中工作。这些表格存在于我们的ERP软件中,因此物理上创建一个新表格是不可行的。我已经修改了答案,将其与一起使用,而不是临时表格。太棒了!这大大加快了我运行的查询速度。这是一个有趣的解决方案,但不幸的是,我在一个非常规范的环境中工作。这些表格存在于我们的ERP软件中,因此物理上创建一个新表格是不可行的。我已经修改了答案,将其与一起使用,而不是临时表格。太棒了!这大大加快了我正在运行的查询的速度。我认为我做不到,我简化并重命名了实际的表我认为我做不到,我简化并重命名了实际的表对不起,您的查询比现有的查询运行得慢。
关税
表在
出口关税
上编制索引,但
项目位置
表是最大的一个。因此,您的查询正在访问该表两次,这使其速度变慢。很抱歉,您的查询运行速度比现有查询慢。
关税
表在
出口关税
上编制索引,但
项目位置
表是最大的一个。因此,您的查询将访问该表两次,这会减慢它的速度。