2

我正在尝试优化 Oracle 查询。现在它运行得很慢,因为该表有大约 1M 的记录。我有两张桌子,item_location桌子和tariffs桌子。一条item_location记录有一个双键,item_noand item_loctariffs记录使用密钥存储,该密钥是tariff_code随机的三位标识符,具有字段import_tariffexport_tariff. item_tariff_code是项目记​​录的外键tariffs

为简单起见,这是一个SQLFiddle

我试图找到item_noexport_tariff' 匹配两个值(包括)的位置。

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

  item_no  |  item_loc  |  export_tariff
----------------------------------------
  12345    |  B1        |  1111111111
  12345    |  B2        |  2222222222

但由于这条记录,它不应该找到“67890”:

  item_no  |  item_loc  |  export_tariff
----------------------------------------
  67890    |  B1        |  1111111111

因为它没有export_tariff“2222222222”。

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

4

4 回答 4

0

像这样的东西?

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' 
于 2012-07-28T08:05:01.650 回答
0

像下面这样的东西应该可以工作:

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'
;
于 2012-07-27T17:01:59.123 回答
0

如果你不能使用临时表,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

顺便说一句,感谢 SQLFiddle,这是一个很棒的网站。

PS:我看不到如何避免item_location两次扫描表,因为您确实必须在item_no. 如果你想快速解决这个问题,你可以使用这样的查询来改变执行顺序:

WITH il AS (
  SELECT
    il1.item_no,
    il1.item_tariff_code AS tc1,
    il2.item_tariff_code AS tc2
  FROM item_location il1
  JOIN item_location il2
    ON il1.item_no = il2.item_no AND
       il1.item_loc <> il2.item_loc)
SELECT item_no FROM il
JOIN tariffs t1
  ON il.tc1 = t1.tariff_code
JOIN tariffs t2
  ON il.tc2 = t2.tariff_code
WHERE
  t1.export_tariff LIKE '3916906000%' AND
  t2.export_tariff LIKE '39191080%'

SQLFiddle上查看

于 2012-07-27T15:25:52.193 回答
0

如果您在 export_tariff 上被索引,也许您可​​以进行两次索引查找并结合结果来查找感兴趣的项目?

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
于 2012-07-27T15:19:55.360 回答