所以,我有像这样的cakephp SQL语句
$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中看起来像:
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;
这个说法有效,但是当我有更大的数据量(用于测试)时它不起作用(执行时间太长)。
价格表有100行,而地方表有3k数据。
有什么方法可以让这句话更快?
答案 0 :(得分:2)
不应在JOIN上使用多个条件。最好让他们在Where条件下。另外,请确保您已将postal
和product_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;