1

私はこのクエリを持っています:

SELECT bi.id, 
       bi.location, 
       bi.expense_group, 
       bi.level, 
       bi.is_active, 
       bi.type, 
       full_name, 
       ( bl.bud_amount )                                     AS BudgetAmount, 
       ( COALESCE(( ( bl.bud_amount * 3 ) - ( 
                    + bal.bal_amount1 + bal.bal_amount2 
                    + bal.bal_amount3 ) ), 0) ) AS Difference, 
       ( COALESCE(Round(( + bal.bal_amount1 + bal.bal_amount2 
                          + bal.bal_amount3 ) / 3), 0) )     AS Average, 
       bal.bal_amount1                                       AS BAL1, 
       bal.bal_amount2                                       AS BAL2, 
       bal.bal_amount3                                       AS BAL3 
FROM   (SELECT * 
        FROM   budget_items bi 
        WHERE  bi.location IS NOT NULL) AS bi 
       LEFT JOIN (SELECT budget_item_id, 
                         Sum(CASE 
                               WHEN budget_id = 21491 THEN amount 
                             END) AS bud_amount 
                  FROM   budget_lines 
                  GROUP  BY budget_item_id) AS bl 
              ON bl.budget_item_id = bi.id 
       JOIN (SELECT budget_item_id, 
                    Ifnull(Sum(CASE 
                                 WHEN balance_id = 12841 THEN amount 
                               END), 0) AS bal_amount1, 
                    Ifnull(Sum(CASE 
                                 WHEN balance_id = 18647 THEN amount 
                               END), 0) AS bal_amount2, 
                    Ifnull(Sum(CASE 
                                 WHEN balance_id = 18674 THEN amount 
                               END), 0) AS bal_amount3 
             FROM   balance_lines 
             GROUP  BY budget_item_id) AS bal 
         ON bal.budget_item_id = bi.id 
ORDER  BY bi.location 

時間がかかります。Budget_lines テーブルと balance_lines テーブルには、それぞれ 5,000,000 行以上あります。

クエリの EXPLAIN も添付しますので、問題を確認することができます。すべてのテーブルのすべての ID にインデックスが付けられます。クエリを高速化するためにインデックスが作成される列はありますか? または多分私はそれを変更する必要があります。

*** 残高/予算行テーブルに存在しない場合でも、nudget_items からすべてのアイテムを取得する必要があるため、LEFT JOIN が必要です。

スキーマは次のとおりです。すべての予算にはbudget_linesがあります。すべての残高には、balance_lines があります。このクエリは、予算と複数の残高の違いを要約する 1 つのテーブルを持つことを目的としています。

ここに画像の説明を入力

ここで大きな画像を見ることができます: http://i.stack.imgur.com/dlF8V.png

編集: @Sebas が回答した後: ここに画像の説明を入力

@sabes の飢餓については、DESCRIBE: Budget_items をここに入力します。 ここに画像の説明を入力

予算_行 ここに画像の説明を入力

バランスライン ここに画像の説明を入力

4

1 に答える 1

0

このようなものかもしれません。ただし、サンプル データとインデックスがないとわかりにくい

SELECT * 
FROM   budget_items bi 
WHERE  bi.location IS NOT NULL) AS bi 
INNER JOIN  --Added inner for clarity  -changed order I just like my inner's before my outers.
  (SELECT budget_item_id, Sum(CASE WHEN balance_id = 12841 THEN coalesce(amount,0) END), 0) AS bal_amount1, 
                          Sum(CASE WHEN balance_id = 18647 THEN coalesce(amount,0) END), 0) AS bal_amount2, 
                          Sum(CASE WHEN balance_id = 18674 THEN coalesce(amount,0) END), 0) AS bal_amount3 
   FROM   balance_lines 
   WHERE balance_ID in (12841, 18647, 18674) --This way balance_IDs which aren't in this list don't even get evaluated
   GROUP  BY budget_item_id) AS bal 
 ON bal.budget_item_id = bi.id 
LEFT JOIN 
 (SELECT budget_item_id, Sum(CASE WHEN budget_id = 21491 THEN coalesce(amount,0) END) AS bud_amount 
  FROM   budget_lines 
  WHERE budget_Id = 21491 --Again since we only care about anything but budget_ID 21491, we can limit the results to JUST that 
  GROUP  BY budget_item_id) AS bl 
 ON bl.budget_item_id = bi.id 
于 2013-03-13T12:47:13.613 に答える