简体   繁体   English

优化SQL语句(离散连接和左连接)CakePhp

[英]Optimize SQL statement (Distinct and left join) CakePhp

So, I have cakephp SQL statement like this 所以,我有像这样的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();

In SQL looks like: 在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;

This statement works, but when I have bigger data amount (for testing) it doesnt work (takes too long to execute). 该语句有效,但是当我有更大的数据量(用于测试)时,它不起作用(执行时间太长)。

Prices table have arount 1M rows, and Places Table arount 3k data. Price表具有1M行,而Places表具有3k数据。

Is there any way how can I make this statement faster? 有什么办法可以使我的陈述更快?

Should not use multiple conditions on JOIN. 不应在JOIN上使用多个条件。 Better to have them on Where condition. 最好让它们处于Where条件。 Also make sure you have indexed columns like postal and product_id to see better performance. 另外,请确保已建立索引列,例如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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM