aex*_*exl 6 cakephp cakephp-3.0
我有一个CakePHP 3 find()调用,我一直试图优化一段时间.我已将其缩小到这两个片段,唯一的区别是contain删除了参数.计时由DebugKit测量.
contain:public function qrytest() {
$table = TableRegistry::get('OrderOptions', array(
'className' => 'App\Model\Table\Opencart\OrderOptionsTable',
));
$results = $table->find('all', array(
'fields' => array(
'OrderOptions.order_product_id',
'OrderOptions.order_option_id',
'OrderOptions.value',
),
'conditions' => array(
'OrderOptions.order_id' => 123,
),
'contain' => array(
'OpencartProductOptions' => array(
'OpencartOption',
),
'OpencartOrderProducts' => array(
'OpencartOrders' => array(
'OpencartShippingZone',
),
'OpencartProduct' => array(
'OpencartWeightClass',
),
),
'OpencartProductOptionValues',
),
))->all();
$this->viewBuilder()->template('anEmptyView');
}
Run Code Online (Sandbox Code Playgroud)
Sql Log:1/99 ms; 定时器:4.42 s/5.72 MB
containpublic function qrytest() {
$table = TableRegistry::get('OrderOptions', array(
'className' => 'App\Model\Table\Opencart\OrderOptionsTable',
));
$results = $table->find('all', array(
'fields' => array(
'OrderOptions.order_product_id',
'OrderOptions.order_option_id',
'OrderOptions.value',
),
'conditions' => array(
'OrderOptions.order_id' => 123,
),
// contain parameter removed; nothing else changed
))->all();
$this->viewBuilder()->template('anEmptyView');
}
Run Code Online (Sandbox Code Playgroud)
Sql Log:1/92 ms; 定时器:1.06秒/4.83 MB
总结:包含contains参数使得控制器花费近5秒的时间进行渲染,同时不会显着改变实际的查询时间.扩展DebugKit的Timers选项卡显示Controller操作:4,388.74 ms(屏幕截图第1 部分,第2部分)
这里首先想到的是优化连接和索引,但是如果你看一下上面的结果,在这两种情况下,查询本身似乎需要相同的时间.为了确认,我在MySQL Workbench中直接运行了原始查询(包括JOIN),大约需要100毫秒,这与我在DebugKit输出中看到的相匹配.此外,我实际上确实在不久前创建了所有必需的索引.
也就是说,我开始认为问题不在于我的MySQL查询,而在于CakePHP如何处理它,这就是我需要帮助的地方.
如果你需要,我可以发布表结构信息.
$query->enableHydration(false);和$query->hydrate(false);(按照查询builder.html#得到阵列,而不是-的实体)'debug' => false,仍然很慢:时间= 4.30秒,由浏览器测量这是生成的查询:
SELECT
`OrderOptions`.`order_product_id` AS `OrderOptions__order_product_id`,
`OrderOptions`.`order_option_id` AS `OrderOptions__order_option_id`,
`OrderOptions`.`value` AS `OrderOptions__value`
FROM
`order_option` `OrderOptions`
LEFT JOIN `product_option` `OpencartProductOptions` ON `OpencartProductOptions`.`product_option_id` = (
`OrderOptions`.`product_option_id`
)
LEFT JOIN `option` `OpencartOption` ON `OpencartOption`.`option_id` = (
`OpencartProductOptions`.`option_id`
)
LEFT JOIN `order_product` `OpencartOrderProducts` ON `OpencartOrderProducts`.`order_product_id` = (
`OrderOptions`.`order_product_id`
)
LEFT JOIN `order` `OpencartOrders` ON `OpencartOrders`.`order_id` = (
`OpencartOrderProducts`.`order_id`
)
LEFT JOIN `zone` `OpencartShippingZone` ON `OpencartShippingZone`.`zone_id` = (
`OpencartOrders`.`shipping_zone_id`
)
LEFT JOIN `product` `OpencartProduct` ON `OpencartProduct`.`product_id` = (
`OpencartOrderProducts`.`product_id`
)
LEFT JOIN `weight_class` `OpencartWeightClass` ON `OpencartProduct`.`weight_class_id` = (
`OpencartWeightClass`.`weight_class_id`
)
LEFT JOIN `product_option_value` `OpencartProductOptionValues` ON `OpencartProductOptionValues`.`product_option_value_id` = (
`OrderOptions`.`product_option_value_id`
)
WHERE
`OrderOptions`.`order_id` = 123
Run Code Online (Sandbox Code Playgroud)这是XDebug输出:
小智 0
我与较大的企业项目合作,前端是 CakePHP,但是当您开始讨论快速开发框架的性能时,您会提出这种框架无法自行处理的需求。
在适当的时候使用 CakePHP,例如显示表中的注册表。
当我进入像你这样的更大的数据集时,我利用数据库资源来解决它们的性能问题,这样我就不会要求 CakePHP 的性能期望。
使用 EXPLAIN,您可以为查询设置适当的索引,当它足够优化时,设置一个简单的视图,例如:
CREATE VIEW %VIEW-NAME% AS %QUERY%
Run Code Online (Sandbox Code Playgroud)
如果使用视图还不够,例如,如果视图仍然具有较大的数据集,请开始使用存储过程,这是一种很好的工作方式,因为您可以使程序的一部分在数据库内运行,并且再次使用 CakePHP 仅用于显示这个数据。
| 归档时间: |
|
| 查看次数: |
524 次 |
| 最近记录: |