在oracle中优化此查询

时间:2013-12-01 17:40:04

标签: sql oracle query-optimization

因为oracle不支持null = null比较我做了这个声明:

SELECT p.nazwa,
       p.nazwa_miedz,
       p.dawka_l_p,
       p.dawka_j_p,
       p.dawka_l_n,
       p.dawka_j_n
FROM   produkt p
WHERE  p.nazwa_miedz LIKE (SELECT pp.nazwa_miedz
                           FROM   produkt pp
                           WHERE  pp.bloz12 = 232440132296)
       AND p.bloz12 != (SELECT pp.bloz12
                        FROM   produkt pp
                        WHERE  pp.bloz12 = 232440132296)
       AND ( p.dawka_l_p = (SELECT pp.dawka_l_p
                            FROM   produkt pp
                            WHERE  pp.bloz12 = 232440132296)
              OR ( p.dawka_l_p IS NULL
                   AND (SELECT pp.dawka_l_p
                        FROM   produkt pp
                        WHERE  pp.bloz12 = 232440132296) IS NULL ) )
       AND ( p.dawka_j_p = (SELECT pp.dawka_j_p
                            FROM   produkt pp
                            WHERE  pp.bloz12 = 232440132296)
              OR ( p.dawka_j_p IS NULL
                   AND (SELECT pp.dawka_j_p
                        FROM   produkt pp
                        WHERE  pp.bloz12 = 232440132296) IS NULL ) )
       AND ( p.dawka_l_n = (SELECT pp.dawka_l_n
                            FROM   produkt pp
                            WHERE  pp.bloz12 = 232440132296)
              OR ( p.dawka_l_n IS NULL
                   AND (SELECT pp.dawka_l_n
                        FROM   produkt pp
                        WHERE  pp.bloz12 = 232440132296) IS NULL ) )
       AND ( p.dawka_j_n = (SELECT pp.dawka_j_n
                            FROM   produkt pp
                            WHERE  pp.bloz12 = 232440132296 IS NULL)
              OR p.dawka_j_n IS NULL
                 AND (SELECT pp.dawka_j_n
                      FROM   produkt pp
                      WHERE  pp.bloz12 = 232440132296) ) 

这个州有什么作用?向我们展示药物的替代品。 bloz12 = 232440132296是产品的ID。我们正在寻找具有相同剂量的产品:dawka_l_p,dawka_j_p,dawka_l_n,dawka_j_n。还有一个AND不显示替换(与原始产品相同)。而最后的AND nazwa_miedz就是医学的实质。我只是想知道这些subquerys是否可以优化..正如你可以看到他们中的很多..我希望有人可以改进它!谢谢!

3 个答案:

答案 0 :(得分:1)

自我加入可能会奏效。这将向您展示一般的想法。

    SELECT p.nazwa,
       p.nazwa_miedz,
       p.dawka_l_p,
       p.dawka_j_p,
       p.dawka_l_n,
       p.dawka_j_n

FROM   produkt p join product p2 on p.dawka_l_p = p2.dawka_l_p
and p.dawka_j_p = p2.dawka_j_p
and p.dawka_l_n = p2.dawka_l_n

WHERE p.bloz12 <> 232440132296
and p2.bloz12 = 232440132296

我可能会遗漏一些细节。

答案 1 :(得分:1)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE produkt (
  bloz12      NUMBER(20),
  nazwa       NUMBER(20),
  nazwa_miedz VARCHAR2(20),
  dawka_l_p   NUMBER(5,2),
  dawka_j_p   NUMBER(5,2),
  dawka_l_n   NUMBER(5,2),
  dawka_j_n   NUMBER(5,2)
);

INSERT INTO produkt
          SELECT 232440132296, 1, 'Reference Sample', 1,1,1,1 FROM DUAL
UNION ALL SELECT 1, 1, 'Reference Sample', 1,1,1,1 FROM DUAL;

查询1

SELECT p.nazwa,
       p.nazwa_miedz,
       p.dawka_l_p,
       p.dawka_j_p,
       p.dawka_l_n,
       p.dawka_j_n
FROM   produkt p
WHERE  EXISTS ( SELECT 1
                FROM   produkt x
                WHERE  x.bloz12 = 232440132296
                AND    p.bloz12 <> x.bloz12
                AND    p.nazwa_miedz LIKE x.nazwa_miedz
                AND    (  p.dawka_l_p = x.dawka_l_p
                       OR (   p.dawka_l_p IS NULL
                          AND x.dawka_l_p IS NULL ) )
                AND    (  p.dawka_j_p = x.dawka_j_p
                       OR (   p.dawka_j_p IS NULL
                          AND x.dawka_j_p IS NULL ) )
                AND    (  p.dawka_l_n = x.dawka_l_n
                       OR (   p.dawka_l_n IS NULL
                          AND x.dawka_l_n IS NULL ) )
                AND    (  p.dawka_j_n = x.dawka_j_n
                       OR (   p.dawka_j_n IS NULL
                          AND x.dawka_j_n IS NULL ) ) )

<强> Results

| NAZWA |      NAZWA_MIEDZ | DAWKA_L_P | DAWKA_J_P | DAWKA_L_N | DAWKA_J_N |
|-------|------------------|-----------|-----------|-----------|-----------|
|     1 | Reference Sample |         1 |         1 |         1 |         1 |

答案 2 :(得分:1)

SELECT p.nazwa,
   p.nazwa_miedz,
   p.dawka_l_p,
   p.dawka_j_p,
   p.dawka_l_n,
   p.dawka_j_n

FROM produkt p join product p2 on p.nazwa_miedz = p2.nazwa_miedz
and (p.dawka_l_p = p2.dawka_l_p or
     p.dawka_l_p is NULL and p2.dawka_l_p is NULL)
and (p.dawka_j_p = p2.dawka_j_p or
     p.dawka_j_p is NULL and p2.dawka_j_p is NULL)
and (p.dawka_l_n = p2.dawka_l_n or
     p.dawka_l_n is NULL and p2.dawka_l_n is NULL)
and (p.dawka_j_n = p2.dawka_j_n or
     p.dawka_j_n is NULL and p2.dawka_j_n is NULL)
WHERE p.bloz12 != 232440132296
and p2.bloz12 = 232440132296

我猜你忘了在

的末尾添加is NULL
...
OR p.dawka_j_n IS NULL
    AND (SELECT pp.dawka_j_n
        FROM   produkt pp
        WHERE  pp.bloz12 = 232440132296)

comparing NULL values记住,如果p.dawka_j_n = p2.dawka_j_n两者都NULL,那么is NULL将不会评估为真,因此如果这是您想要的话,则必须明确地使用{{1}}进行检查。