英文:
PHP: memory issues while looping thousand of items
问题
这是一个WordPress与WooCommerce项目。
我必须循环遍历一个包含超过20万个项目的数组。每个项目都是数据库中的一个订单ID。我必须对每个订单的元数据求和以得到总和。但是循环总是出现内存问题。
以下是我的代码:
function woq_orders_total(){
$orders = get_option( 'woq_orders_ids' ); // ID数组
$meta = array();
$i = 0;
foreach( $orders as $order ) :
$meta[] = get_post_meta( $order, '_order_total', true );
if ( $i % 500 == 0 )
sleep( 5 ); // 每500个项目停顿5秒
$i++;
endforeach;
update_option( 'woq_orders_total', array_sum( $meta ) );
}
我尝试每100个项目停顿一次,但问题仍然存在。这在处理少量项目时效果良好,但在处理这么多项目时不起作用。
感谢任何帮助。
英文:
This is a WordPress with Woocommerce project.
I have to loop an array with more than 200 thousand of items. Every item is an order's ID in the data base. I have to sum the value of every order's meta to get the total sum. But the loop allways ends with memory issue.
Here is my code:
function woq_orders_total(){
$orders = get_option( 'woq_orders_ids' ); // array of IDs
$meta = array();
$i = 0;
foreach( $orders as $order ) :
$meta[] = get_post_meta( $order, '_order_total', true );
if ( $i % 500 == 0 )
sleep( 5 ); // stop for 5 seconds every 500 items
$i++;
endforeach;
update_option( 'woq_orders_total', array_sum( $meta ) );
}
I've try stoping every 100 items, but the problem persists. This works well with a few numbers of items, but not with this big amount.
Thanks for any help
答案1
得分: 2
你不必将所有数据读入数组中以进行求和。
你只需要存储总和。
```php
function woq_orders_total(){
$orders = get_option( 'woq_orders_ids' ); // array of IDs
$total = 0;
foreach( $orders as $order ) :
$total += (float)get_post_meta( $order, '_order_total', true );
endforeach;
update_option( 'woq_orders_total', $total);
}
<details>
<summary>英文:</summary>
You don't have to read all the data into the array to sum them up.
You only need to store the sum.
```php
function woq_orders_total(){
$orders = get_option( 'woq_orders_ids' ); // array of IDs
$total = 0;
foreach( $orders as $order ) :
$total += (float)get_post_meta( $order, '_order_total', true );
endforeach;
update_option( 'woq_orders_total', $total);
}
答案2
得分: 2
我已经找到了一个解决方案,感谢 Markus AO 的评论。
现在我的代码看起来像这样:
function woq_orders_total(){
global $wpdb;
$orders = get_option( 'woq_orders_ids' );
$orders = join( ',', $orders );
$meta_key = '_order_total';
$total = $wpdb->get_var(
$wpdb->prepare(
"
SELECT SUM(meta_value)
FROM $wpdb->postmeta
WHERE meta_key = %s
AND post_id IN ({$orders})
",
$meta_key
)
);
update_option( 'woq_orders_total', $total );
}
另外,$wpdb
文档中的这些评论对我帮助很大:https://developer.wordpress.org/reference/classes/wpdb/#comment-1975
谢谢大家。
英文:
I've found a solution thanks to the comment by Markus AO
Now my code looks like this:
function woq_orders_total(){
global $wpdb;
$orders = get_option( 'woq_orders_ids' );
$orders = join( ',', $orders );
$meta_key = '_order_total';
$total = $wpdb->get_var(
$wpdb->prepare(
"
SELECT SUM(meta_value)
FROM $wpdb->postmeta
WHERE meta_key = %s
AND post_id IN ({$orders})
",
$meta_key
)
);
update_option( 'woq_orders_total', $total );
}
Also these comment in $wpdb
documentation help a lot https://developer.wordpress.org/reference/classes/wpdb/#comment-1975
Thanks you all.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论