2017-02-27 14 views
1

所以,我有这样的优化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(); 

在SQL看起来像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行,Places Table arount 3k数据。

有什么办法可以让我的声明更快?

+0

insted使用左连接内的condinions,为什么不使用简单的where条件外加入? – 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,问题是在多个条件....现在只需要2s :) – JohnWayne

+2

太棒了!同时添加索引,当您在Lac中有大量记录时,您会看到更好的性能 – Naincy