【问题标题】:DB2 SQL Tips/HintsDB2 SQL 提示/提示
【发布时间】:2011-10-17 17:12:10
【问题描述】:

我在我的应用程序的一部分中使用了这个语句,它是生成的。 LIKE '%%' 是空的,只是因为没有向它发送搜索参数,所以它会拉入所有结果。

我对整个数据库还是个新手,想知道是否有任何提示可以改进我的陈述?

我确定它看起来很糟糕,但请放轻松!

更新:我主要希望从中获得更好的性能。我已经使用了 DB2 顾问并创建了它说我应该制作的密钥。这对一些人有所帮助,但仍然比我希望的要慢。

谢谢。

SELECT * FROM 
(
    SELECT rownumber() OVER (ORDER BY pgmajdsc, item) AS ROW_NUM, 
    line, item, pgmajdsc, manufacturer 
    FROM 
    (
        SELECT iline AS line, iitem AS item, pgmajdsc, ldesc AS manufacturer 
        FROM itemmast 
        LEFT JOIN itemweb on iline=line and iitem=item 
        JOIN linemst ON iline=lline 
        LEFT JOIN custord ON opline=iline AND opitem=iitem AND opcust='1234' 
        LEFT JOIN cartwdtl ON cwline=iline and cwitem=iitem and cwusr='foo' AND cwcust='1234' 
        LEFT JOIN itematr ON iline=ialine AND iitem=iaitem 
        LEFT JOIN prodgrp ON iaclass=pgclass 
        WHERE ico = 01 
        AND iecomm = 'Y' 
        AND (UPPER(ITEMDESC) LIKE '%%' OR UPPER(PRODDESC) LIKE '%%' OR 
            LINE LIKE '%%' OR UPPER(MFGNAME) LIKE '%%' OR ITEM LIKE '%%' OR 
            PRODNAME LIKE '%%' OR IDESC1 LIKE '%%' OR IDESC2 LIKE '%%' OR 
            IMFGNO LIKE '%%' OR IITEM LIKE '%%')
    ) AS TEMP
) AS ROW_NUM  
WHERE ROW_NUM BETWEEN 0 AND 25 
ORDER BY pgmajdsc, item

【问题讨论】:

  • 除了格式化还有什么想改进的?
  • 您可以尝试将其分成不同的行,以便更好地阅读:D
  • @Bead 不用说,您应该重新格式化这个查询,以便人类和 DB2 的解析器都能解释它。不过,除此之外,您还需要重新表述这个问题,以便它提出一个特定问题。目前尚不清楚您要回答什么。
  • LIKE '%%' 是全表扫描...这会在大表上杀死你。
  • 要么改变功能,所以它只是一个尾随的'%',或者考虑实现某种类型的全文搜索......这不是微不足道的。但是,我更担心看起来像 SQL 注入漏洞的东西。构建并调用此查询的代码是什么?

标签: sql db2 query-optimization


【解决方案1】:

假设您正在使用类似子句的参数,我要更改的第一件事是检查它是否为空的语句,它将避免所有其他比较。另一个更改是删除嵌套。通过使用 Fetch first 子句,您可以达到相同的效果(我认为无论如何)。

注意:这是未经测试的,因为目前我面前没有数据库,但我很确定它会起作用。

SELECT rownumber() OVER (ORDER BY pgmajdsc, item) AS ROW_NUM, 
       iline AS line, iitem AS item, pgmajdsc, ldesc AS manufacturer 
FROM itemmast 
   LEFT JOIN itemweb on iline=line and iitem=item 
   JOIN linemst ON iline=lline 
   LEFT JOIN custord ON opline=iline AND opitem=iitem AND opcust='1234' 
   LEFT JOIN cartwdtl ON cwline=iline and cwitem=iitem and cwusr='foo' AND cwcust='1234' 
   LEFT JOIN itematr ON iline=ialine AND iitem=iaitem 
   LEFT JOIN prodgrp ON iaclass=pgclass 
WHERE ico = 01 
  AND iecomm = 'Y' 
  AND (parameter IS NULL 
       OR (UPPER(ITEMDESC) LIKE '%'||parameter||'%' 
       OR UPPER(PRODDESC) LIKE '%'||parameter||'%'
       OR LINE LIKE '%'||parameter||'%' 
       OR UPPER(MFGNAME) LIKE '%'||parameter||'%' 
       OR ITEM LIKE '%'||parameter||'%' 
       OR PRODNAME LIKE '%'||parameter||'%' 
       OR IDESC1 LIKE '%'||parameter||'%' 
       OR IDESC2 LIKE '%'||parameter||'%' 
       OR IMFGNO LIKE '%'||parameter||'%' 
       OR IITEM LIKE '%'||parameter||'%') )
ORDER BY ROW_NUM, pgmajdsc, item
FETCH FIRST 25 ROWS ONLY

编辑:另一个想法是,除非您确实需要行号,否则您可以将其省略,然后按如下方式进行订购:

SELECT iline AS line, iitem AS item, pgmajdsc, ldesc AS manufacturer 
FROM itemmast 
   LEFT JOIN itemweb on iline=line and iitem=item 
   JOIN linemst ON iline=lline 
   LEFT JOIN custord ON opline=iline AND opitem=iitem AND opcust='1234' 
   LEFT JOIN cartwdtl ON cwline=iline and cwitem=iitem and cwusr='foo' AND cwcust='1234' 
   LEFT JOIN itematr ON iline=ialine AND iitem=iaitem 
   LEFT JOIN prodgrp ON iaclass=pgclass 
WHERE ico = 01 
  AND iecomm = 'Y' 
  AND (parameter IS NULL 
       OR (UPPER(ITEMDESC) LIKE '%'||parameter||'%' 
       OR UPPER(PRODDESC) LIKE '%'||parameter||'%'
       OR LINE LIKE '%'||parameter||'%' 
       OR UPPER(MFGNAME) LIKE '%'||parameter||'%' 
       OR ITEM LIKE '%'||parameter||'%' 
       OR PRODNAME LIKE '%'||parameter||'%' 
       OR IDESC1 LIKE '%'||parameter||'%' 
       OR IDESC2 LIKE '%'||parameter||'%' 
       OR IMFGNO LIKE '%'||parameter||'%' 
       OR IITEM LIKE '%'||parameter||'%') )
ORDER BY pgmajdsc, item
FETCH FIRST 25 ROWS ONLY

我不知道计算行号对性能的影响有多大,但如果你不需要它,就不需要返回它。

【讨论】:

  • 好吧,我确实使用了这个 WHERE ROW_NUM BETWEEN 0 和 25,我会根据用户所在的页面更改它,所以下一个可能是 26-50。
  • 请注意,SQL 标准(以及 DB2 也是)遵循短路逻辑;事实上,manual p.201(假设为 iSeries)声明“括号内的条件首先被评估”。不过,我仍然可能会按照这些思路构建语句:它允许基于参数的存在来“关闭”条件,而无需求助于动态 SQL(优化器似乎能够识别这一点,并做出适当的响应,无论如何)。
猜你喜欢
  • 2018-12-25
  • 2023-04-05
  • 1970-01-01
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 2016-04-07
  • 2022-10-31
  • 2012-04-13
相关资源
最近更新 更多