当前位置: 首页 > 面试题库 >

使用SQL搜索DB2进行分页的最快,最高效的方法

孙渝
2023-03-14
问题内容

现在,我执行两个单独的SQL语句,一个执行SELECT COUNT(*)与搜索语句基本相同的条件。我并不是最擅长做出这些陈述,有时会有点慢,我想知道是否有更好的方法来做我所做的事情。可能只执行一个SQL语句,并在PHP中做更多工作?这是我有陈述的“搜索包含”示例。

在第二条语句中,您将看到Y之间的X,这部分是由第一行计数语句的结果计算得出的。

SQL行数:

SELECT COUNT(*) 
FROM itemmast 
LEFT OUTER JOIN itemweb 
ON iline = line 
AND iitem = item 
JOIN linemst 
ON iline = lline 
LEFT OUTER JOIN custord 
ON opline = iline 
AND opitem = iitem 
AND opcust = '12345' 
LEFT OUTER JOIN ordwdtl 
ON owline = iline 
AND owitem = iitem 
AND owusr ='user' 
AND owcust ='12345' 
WHERE ico = 01 
AND iecomm = 'Y'  
AND (UPPER(ITEMDESC) || UPPER(PRODDESC)) LIKE '%FOO%' 
     OR LINE LIKE '%FOO%' 
     OR UPPER(MFGNAME) LIKE '%FOO%' 
     OR UPPER(ITEM) LIKE '%FOO%' 
     OR UPPER(PRODNAME) LIKE '%FOO%' 
     OR UPPER(IDESC1 || IDESC2) LIKE '%FOO%' 
     OR UPPER(IMFGNO) LIKE '%FOO%' 
     OR UPPER(IITEM) LIKE '%FOO%')

SQL搜索:

SELECT * 
FROM (SELECT iline AS line, iitem AS item, rownumber() OVER (ORDER BY item) AS ROW_NUM 
      FROM itemmast 
      LEFT OUTER JOIN itemweb 
      ON iline = line 
      AND iitem = item 
      JOIN linemst 
      ON iline = lline 
      LEFT OUTER JOIN custord 
      ON opline = iline 
      AND opitem = iitem 
      AND opcust = '12345' 
      LEFT OUTER JOIN ordwdtl 
      ON owline = iline 
      AND owitem = iitem 
      AND owusr = 'user' 
      AND owcust = '12345' 
      WHERE ico = 01 
      AND iecomm = 'Y' 
      AND (UPPER(ITEMDESC) || UPPER(PRODDESC)) LIKE '%FOO%' 
           OR LINE LIKE '%FOO%' 
           OR UPPER(MFGNAME) LIKE '%FOO%' 
           OR UPPER(ITEM) LIKE '%FOO%' 
           OR UPPER(PRODNAME) LIKE '%FOO%' 
           OR UPPER(IDESC1 || IDESC2) LIKE '%FOO%' 
           OR UPPER(IMFGNO) LIKE '%FOO%' 
           OR UPPER(IITEM) LIKE '%FOO%')) 
      AS TEMP 
WHERE ROW_NUM BETWEEN 0 AND 25

问题答案:

如果您要显示结果的总计数和分页计数(因此38中为‘0到25’),那么最好的选择是单独声明。我已经尝试了很多方法来获取各个行旁边的计数,但是性能(即使在中等测试数据库上)也很糟糕。

您可能应该做的是创建一个可以查询的视图,其中包含所有选择条件,然后将其包装为必需的行为即可:
Count:

SELECT COUNT(*)
FROM view

排名行:

SELECT *
FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY item) as RANK
      FROM view) as TEMP
WHERE RANK BETWEEN 0 AND 25

您当然需要添加相对where条件,但这是视图要处理的事物类型。

如果您实际上不需要提前知道总行数,则只需将最终排名设置为开始排名加上一些偏移即可。然后,当您使用PHP显示结果时,只需编辑结尾显示值。

一些随机的注释:1)是否有line不是upper()d的原因?
2)仅仅因为所有的字符串操作/比较,此查询的性能几乎将受到影响,无论您做什么。是否有可能消除或忽略某些条件?除非已将用于各种字符串列的索引upper应用于它们(某些更高版本的DB2允许将某些标量函数应用于索引键),否则大多数索引将完全无用(这并不能帮助您“重新寻找%ANYTHING%毕竟)。

好的,有一种“棘手”的方法可以执行类似的操作,并且似乎可以获得良好的性能…尝试这样的操作(首先定义一个视图确实会有所帮助):

SELECT TEMP.*, CASE WHEN RANK = 0 THEN (SELECT COUNT(*)
                                        FROM view)
                    ELSE 0 END
FROM (SELECT *, ROW_NUMBER() OVER(ORDER BY item) as RANK
      FROM view) as TEMP
WHERE RANK BETWEEN 0 AND 25

当然,您仍然必须where在subselect中定义您的子句…



 类似资料:
  • 问题内容: 我有一个数据库,其中有75,000+行,每天添加500多个条目。 每行都有标题和描述。 我创建了一个RSS feed,为您提供了特定搜索词的最新条目(例如,http://site.com/rss.rss?q = Pizza将为搜索词“ Pizza”输出RSS)。 我想知道什么是为此编写SQL查询的最佳方法。现在我有: 但是问题是执行查询需要2到10秒。 有没有更好的方法来编写查询,我是

  • 我正在大文本文件中搜索匹配项,但我发现它太慢了。这是文件结构: 我正在尝试匹配第一列的文本,我想提取第二列的值。列之间用\t隔开,大约有1000万行。用不同的单词多次搜索文件。什么搜索方法的时间效率最好? 编辑:文件大小为129 Mb,将被搜索至少数千次。EDIT2:文件是按字母顺序排序的,只有当单词有不同的大写字母时,它们才能出现多次。例如:单词都是不同的条目。

  • 问题内容: 当您执行类似列表在哪里的操作时,python会在列表上进行顺序搜索吗​​?还是创建哈希表表示来优化查找?在应用程序中,我需要这样做,因为我将在列表上进行很多查找,所以最好先执行诸如此类的操作,然后执行?还要注意,我将拥有的值列表将没有重复的数据,而且我实际上并不在乎它的顺序。我只需要能够检查值的存在。 问题答案: 还要注意,我将拥有的值列表将没有重复的数据,而且我实际上并不在乎它的顺序

  • 问题内容: 在C ++和/或Java中实现语音搜索的最有效方法是什么?通过语音搜索,我的意思是替换听起来相似的元音或辅音。这对于名字特别有用,因为有时人们的名字会有一些奇怪的拼写。 我认为替换元音和一些辅音可能是有效的。最好包含一些特殊情况,例如末尾的静音E或F和PH。最好在C ++中使用cstrings或字符串吗?将替换的值存储在内存中或在每次寻找内容时调用函数会更好吗? 问题答案: Sound

  • 问题内容: 我要克隆具有单个主键(PrimKey)的多个表的行。在SQL Server 2005中克隆行的最快方法是什么? 这是一个例子 克隆PrimKey1以获取PrimKey2。所以我尝试以下方法: 但是,这里的问题当然是,内部SELECT语句中重复了列PrimKey。还有其他与上述简单类似的方法吗? 谢谢大家的答复。我继续写了一个函数来处理我的应用程序。我不使用存储的Procs或Temp表,

  • 这篇文章展示了对DB2中的数据进行分页的一些操作: 在MySQL中,我可以使用 若要获取总行数,请执行以下操作。第一部分很容易在DB2的最新版本中复制。我在Google上找不到任何与第二个查询相当的结果(我不想要临时表、子查询或其他荒谬的低效解决方案)。