[ 検索ページ |
一覧表示 |
ツリー表示 |
MLトップ |
トップページ ]
[comu-ml 0103] Re: 規格数が多い場合に「規格」編集画面に移動できない
- From: Kentaro Ohkouchi (Loop AZ) <ohkouchi@loop-az.jp>
- Date: Sun, 01 Jul 2007 03:32:06 +0900 (JST)
大河内です.
ちょっと反応が遅れてしまいました...
From: 神谷 浩之 <kamiya@s-cubism.jp>
Subject: [comu-ml 0102] 規格数が多い場合に「規格」編集画面に移動できない
Date: Wed, 27 Jun 2007 12:46:03 +0900
>
> 開発に関わるモノの性(さが)なのかもしれませんが、恒常的に忙しく
> ちょっとでも空いた隙を見計らって投稿しております ^-^;
お疲れ様です.
僕の場合は, 超多忙な時期は現実逃避でオープンソースに携わっていたりしま
した.
最近, やっと鎮火してきましたが...
以下, 長い引用になってしまいますがご了承下さい.
>
> ■規格数が多い場合に「規格」編集画面に移動できない
snip...
> select文 に含まれる vw_cross_products_class といったサブクエリが
> 展開されて(規格数が多い場合)膨大なテーブルが作成されているようです。
>
> 早い段階で product_id で絞込みができるので、vw_cross_products_class
> を使わずに済む SQL に変えたところ、耐えうる処理時間内に返ってくるように
> なりました。
>
> # 変更前 18分(通常はタイムアウト) ⇒ 変更後 1秒以内
>
>
> DB構造を正確に把握できている方(ロックオン様?)に見て頂きたいのですが
> お願いできますでしょうか?
> メール末尾に参考SQLを記載します。 (MySQL 4.1)
>
> 同じく、「規格」を押した次の画面の「削除」を押した際の処理も
> 非常に時間がかかっております。
> (こちらは原因を追跡しきれておりません)
>
snip...
> 【参考】
>
> ■オリジナル
>
> $objQuery = new SC_Query();
>
> $col = "class_id1, class_id2, name1, name2, rank1, rank2, ";
> $col.= "product_class_id, product_id, T1_classcategory_id AS classcategory_id1, T2_classcategory_id AS classcategory_id2, ";
> $col.= "product_code, stock, stock_unlimited, sale_limit, price01, price02, status";
>
> $sql = "SELECT $col FROM ";
> $sql.= "( ";
> $sql.= "SELECT T1.class_id AS class_id1, T2.class_id AS class_id2, T1.classcategory_id AS T1_classcategory_id, T2.classcategory_id AS T2_classcategory_id, T1.name AS name1, T2.name AS name2, T1.rank AS rank1, T2.rank AS rank2 ";
> $sql.= "FROM dtb_classcategory AS T1, dtb_classcategory AS T2 ";
> $sql.= "WHERE T1.class_id IN (SELECT class_id1 FROM vw_cross_products_class AS crs_prd WHERE product_id = ? GROUP BY class_id1, class_id2) AND T2.class_id IN (SELECT class_id2 FROM vw_cross_products_class AS crs_prd WHERE product_id = ? GROUP BY class_id1, class_id2)";
> $sql.= ") AS T1 ";
>
> $sql.= "LEFT JOIN (SELECT * FROM dtb_products_class WHERE product_id = ?) AS T3 ";
> $sql.= "ON T1_classcategory_id = T3.classcategory_id1 AND T2_classcategory_id = T3.classcategory_id2 ";
> $sql.= "ORDER BY rank1 DESC, rank2 DESC";
>
>
>
> ■修正
> (vw_cross_products_classを事前展開し、必要なカラムのみにして、
> product_idで先に絞り込むようにしたもの)
>
> $col = "class_id1, class_id2, name1, name2, rank1, rank2, ";
> $col.= "product_class_id, product_id, T1_classcategory_id AS classcategory_id1, T2_classcategory_id AS classcategory_id2, ";
> $col.= "product_code, stock, stock_unlimited, sale_limit, price01, price02, status";
>
> $sql = "SELECT $col FROM ";
> $sql.= "( ";
> $sql.= "SELECT T1.class_id AS class_id1, T2.class_id AS class_id2, T1.classcategory_id AS T1_classcategory_id, T2.classcategory_id AS T2_classcategory_id, T1.name AS name1, T2.name AS name2, T1.rank AS rank1, T2.rank AS rank2 ";
> $sql.= "FROM dtb_classcategory AS T1, dtb_classcategory AS T2 ";
>
> $sql.= "WHERE T1.class_id IN (SELECT TTT1.class_id FROM dtb_classcategory AS TTT1, dtb_classcategory AS TTT2 LEFT JOIN dtb_products_class AS TT2 ON TTT1.classcategory_id = TT2.classcategory_id1 AND TTT2.classcategory_id = TT2.classcategory_id2 WHERE TT2.product_id = ?)";
>
> $sql.= " AND T2.class_id IN (SELECT TSS2.class_id FROM dtb_classcategory AS TSS1, dtb_classcategory AS TSS2 LEFT JOIN dtb_products_class AS TS2 ON TSS1.classcategory_id = TS2.classcategory_id1 AND TSS2.classcategory_id = TS2.classcategory_id2 WHERE TS2.product_id = ?)";
>
> $sql.= ") AS T1 ";
>
> $sql.= "LEFT JOIN (SELECT * FROM dtb_products_class WHERE product_id = ?) AS T3 ";
> $sql.= "ON T1_classcategory_id = T3.classcategory_id1 AND T2_classcategory_id = T3.classcategory_id2 ";
> $sql.= "ORDER BY rank1 DESC, rank2 DESC";
>
>
この箇所は, 当方でも問題視しておりましたが,
下記環境で規格数を300件程度まで試した結果, 50〜70ms 程度で返ってきてい
ましたので, ミッションクリティカルな案件でなければ大丈夫であろうと考え
ていました.
テスト環境
PowerMac G5 Dual 2.3GHz Mac OS X 10.4.7
PostgreSQL 8.1.4
ちなみに, vw_cross_products_class を使用しないようチューニングして頂い
たクエリを試してみたところ, PostgreSQL では下記のエラーとなってしまい
ました.
ERROR: invalid reference to FROM-clause entry for table "ttt1"
HINT: There is an entry for table "ttt1", but it cannot be referenced from this part of the query.
原因は, vw_cross_products_class の代りに使用しているサブクエリで, LEFT
JOIN しないテーブルのカラムを LEFT JOIN の結合条件にしているためだと思
われます.
(SELECT
TTT1.class_id
FROM dtb_classcategory AS TTT1, <- これを
dtb_classcategory AS TTT2
LEFT JOIN dtb_products_class AS TT2
ON TTT1.classcategory_id = TT2.classcategory_id1 <- ここで結合
AND TTT2.classcategory_id = TT2.classcategory_id2
WHERE TT2.product_id = ?)
同様にその次にある T2.class_id の IN 句のサブクエリも同様のエラーとな
ります.
MySQL で上手くいっているのでしたら, DB によって処理を分けるのも手だと
思いますが, 規格数が膨大にならなければ, さほど問題にならないと思います
ので, 規格数が多い場合のチューニング例としておく方が良いかもしれません
ね.
しかし, PostgreSQL の場合, 7.x 系と, 8.x 系ではかなり性能差が出るので,
7.x 系を使用している場合は心配です.
また時間を見つけてテストしてみたいと思います.
----------------------------------------------
大河内健太郎(Kentaro Ohkouchi)
E-mail: ohkouchi@loop-az.jp
有限会社Loop AZ
http://www.loop-az.co.jp/
----------------------------------------------
[ 検索ページ |
一覧表示 |
ツリー表示 |
MLトップ |
トップページ ]