2

Oracleクエリを最適化しようとしています。現在、テーブルには最大100万レコードがあるため、実行速度はかなり遅くなります。テーブルとテーブルの2つのテーブルがitem_locationありtariffsます。レコードには、とのitem_locationデュアルキーがitem_noありitem_locます。tariffsレコードは、フィールドと。を含むランダムな3桁の識別子であるキーとともに保存されtariff_codeます。は、アイテムのレコードの外部キーです。import_tariffexport_tariffitem_tariff_codetariffs

簡単にするために、SQLFiddleを次に示します。

2つの値を含むに一致する'sをitem_no持つ場所を見つけようとしています。export_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

export_tariffでインデックスが作成されている場合、2つのインデックス付きルックアップを実行し、結果を組み合わせて関心のあるアイテムを見つけることができますか?

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 に答える
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をありがとう、それは素晴らしいサイトです。

item_locationPS:本当に結合を行う必要があるため、テーブルのスキャンを2回回避する方法がわかりません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

次のようなものが機能するはずです。

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

このようなもの?

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 に答える