2011-08-09 10 views
3

今私は2つの別個のSQL文を実行します.1つは、検索文と基本的に同じ基準でSELECT COUNT(*)を実行します。私はこれらの声明を作成する上で最善ではないし、時には少し遅く、私がやることをやるためのよりよい方法があるかどうかを知りたいと思う。おそらく、PHPでSQL文を1つだけやって、もう少し作業をしているのでしょうか?ここには "検索が含まれています"という例があります。SQL検索でページ区切りを行う最も高速で効率的な方法DB2

2番目のステートメントでは、最初の行カウントステートメントの結果によって部分的に計算される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 

答えて

6

を使用すると、0のうち25に」ページ番号付きのカウントと一緒に結果の合計数を表示しようとする(そうしている場合38)、別の声明があなたの最善の策かもしれません。私は個々の行に並んでカウントを得るために多くのことを試しましたが、パフォーマンスは(中程度のテストデータベースでさえ)ひどいものです。

あなたはおそらく、やるべきことは、その後だけで、必要な行動でそれをラップし、すべてのあなたの選択基準が含まれている、あなたはに対して照会することができますビューを作成します
数:

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 

もちろん、条件の相対的な位置を追加する必要がありますが、これはビューが扱うものの種類です。

事前に合計行を知る必要がない場合は、エンドランクを開始ランクにオフセットを加えたものに設定するだけで済みます。次に、PHPで結果を表示するときに、終了表示値を編集するだけです。

いくつかのランダムなノート: 1)lineupper()でない理由がありますか?
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句を定義する必要があります。

+0

まず、長い、詳細な返信をありがとうございます。私はreasonラインがupper()ではないと思うのは、それがすでにupperとして保存されていて変換が必要ないからです。私はそれが他のフィールドの場合であるかどうかをチェックし、upper()を削除して、それが同様に役立つかどうかを確認します。私は他の人と意見を交わす必要があります。これはIよりもはるかに専門家です。これは私が書いた最初に生成されたSQLステートメントの1つで、それはちょっと面倒です:) – Bead

+0

それはあまりにも面倒ではありません。文字列の連結を削除し、列を別々に 'upper()'したいかもしれませんが。 –

関連する問題