2017-02-27 10 views
1

だから、私はSQLではこの最適化SQL文(個別および参加左)CakePHPの

$groupId = $this->request->data['group_id']; 
     $placesT = TableRegistry::get('Places'); 
     $AllPrices = $placesT->find('all') 
      ->select(['Places.postal', 'Places.city', 'Places.district', 'Places.state', 'Places.country', 'Prices.delivery_price', 'Prices.retrieval_price', 'Prices.maintenance_price', 
       'Prices.edm_price', 'Prices.weighting_price', 'Prices.price_type_fixed_price', 'Prices.price_type_weight_price_per_ton', 'Prices.fee_per_day']) 
      ->leftJoin(
       ['Prices' => 'prices'], 
       [ 
        'Prices.group_id' => $groupId, 
        'Prices.product_id' => $id, 
        'Prices.valid_to >' => (time() * 1000), 
        'Prices.postal = Places.postal', 
       ] 
       , ['Prices.group_id' => 'integer', 'Prices.product_id' => 'integer', 'Prices.valid_to' => 'integer', 'Prices.postal' => 'integer']) 
      ->distinct() 
      ->orderAsc('Places.postal') 
      ->toArray(); 

のようなcakephpのSQLステートメントは、のように見えるしている:

SELECT DISTINCT places.postal AS `Places__postal`, 
       places.city AS `Places__city`, 
       places.district AS `Places__district`, 
       places.state AS `Places__state`, 
       places.country AS `Places__country`, 
       prices.delivery_price AS `Prices__delivery_price`, 
       prices.retrieval_price AS `Prices__retrieval_price`, 
       prices.maintenance_price AS `Prices__maintenance_price`, 
       prices.edm_price AS `Prices__edm_price`, 
       prices.weighting_price AS `Prices__weighting_price`, 
       prices.price_type_fixed_price AS `Prices__price_type_fixed_price`, 
       prices.price_type_weight_price_per_ton AS `Prices__price_type_weight_price_per_ton`, 
       prices.fee_per_day AS `Prices__fee_per_day` 
FROM places 
LEFT JOIN prices ON (prices.group_id = '3' 
          AND prices.product_id = '1' 
          AND prices.valid_to > 1488186767000 
          AND prices.postal = places.postal) 
ORDER BY places.postal ASC; 

この文は動作しますが、私は大きな持っているときデータ量(テストのため)それは仕事をしません(実行に時間がかかります)。

価格表には1M行の行があり、プレイス表には3KBのデータがあります。

この文をより速くする方法はありますか?

+0

左のジョイントの内側にあるそのジョイントを使用していますか? – Whencesoever

+0

「価格」表(例:product_id)にインデックスがありますか? – lpg

答えて

2

JOINで複数の条件を使用しないでください。条件を満たした方が良い。また、より良いパフォーマンスを確認するには、postalproduct_idのようなインデックス付きの列があることを確認してください。

SELECT DISTINCT places.postal AS `Places__postal`, 
       places.city AS `Places__city`, 
       places.district AS `Places__district`, 
       places.state AS `Places__state`, 
       places.country AS `Places__country`, 
       prices.delivery_price AS `Prices__delivery_price`, 
       prices.retrieval_price AS `Prices__retrieval_price`, 
       prices.maintenance_price AS `Prices__maintenance_price`, 
       prices.edm_price AS `Prices__edm_price`, 
       prices.weighting_price AS `Prices__weighting_price`, 
       prices.price_type_fixed_price AS `Prices__price_type_fixed_price`, 
       prices.price_type_weight_price_per_ton AS `Prices__price_type_weight_price_per_ton`, 
       prices.fee_per_day AS `Prices__fee_per_day` 
FROM places 
LEFT JOIN prices ON prices.postal = places.postal 
WHERE prices.group_id = '3' 
    AND prices.product_id = '1' 
    AND prices.valid_to > 1488186767000 
ORDER BY places.postal ASC; 
+0

Thx、問題は複数の条件にあった....今は2秒しかかかりません:) – JohnWayne

+2

素晴らしい!また、索引を追加すると、Lacsに膨大な数のレコードがある場合にパフォーマンスが向上します – Naincy

関連する問題