mysql导致cpu 跑到 90% 以上... 有没有什么好的解决方法.

2016-07-07 15:11 来源:www.chinab4c.com 作者:ecshop专家



这个看到论坛也有不少咨询

但是没有找到好的解决方法

未命名.jpg

商品类型 商品属性 我已经全部都删除掉了..

商品数量有 1万多个

订单数量 5 万多个

用户数 3万多


我的服务器是 两颗 志强E5504的四核cpu
都能跑满


--------------------------------------------------------------
我研究了一上午
貌似稳定了很多
发布下我暂时的解决方案

通过 mysql里面
列出的进程
发现出现问题总是 会有

SELECT g.goods_id, g.goods_name, g.shop_price,

这么一段东西

在 includs/lib_goods.php
里面找到这段东西是销售排行
你可以把以下内容全部删除
  1. /**
  2. * 调用当前分类的销售排行榜
  3. *
  4. * @access public
  5. * @param string $cats 查询的分类
  6. * @return array
  7. */
  8. function get_top10($cats = '')
  9. {
  10. require_once(ROOT_PATH . '/includes/lib_base.php');
  11. $arr = read_static_cache('top_10');
  12. $top10_check = $GLOBALS['db']->getOne('SELECT value FROM '.$GLOBALS['ecs']->table('shop_config').' WHERE code="top10_check"');
  13. if($arr === false || $top10_check < date('Ymd'))
  14. {
  15. //edit by zzl 2011826
  16. // $cats = get_children($cats);
  17. //$where = !empty($cats) ? "AND ($cats OR " . get_extension_goods($cats) . ") " : '';
  18. $where = '';

  19. /* 排行统计的时间 */
  20. switch ($GLOBALS['_CFG']['top10_time'])
  21. {
  22. case 1: // 一年
  23. $top10_time = "AND o.order_sn >= '" . date('Ymd', gmtime() - 365 * 86400) . "'";
  24. break;
  25. case 2: // 半年
  26. $top10_time = "AND o.order_sn >= '" . date('Ymd', gmtime() - 180 * 86400) . "'";
  27. break;
  28. case 3: // 三个月
  29. $top10_time = "AND o.order_sn >= '" . date('Ymd', gmtime() - 90 * 86400) . "'";
  30. break;
  31. case 4: // 一个月
  32. $top10_time = "AND o.order_sn >= '" . date('Ymd', gmtime() - 30 * 86400) . "'";
  33. break;
  34. default:
  35. $top10_time = '';
  36. }

  37. $sql = 'SELECT g.goods_id, g.goods_name, g.shop_price, g.goods_thumb, SUM(og.goods_number) as goods_number ' .
  38. 'FROM ' . $GLOBALS['ecs']->table('goods') . ' AS g, ' .
  39. $GLOBALS['ecs']->table('order_info') . ' AS o, ' .
  40. $GLOBALS['ecs']->table('order_goods') . ' AS og ' .
  41. "WHERE g.is_on_sale = 1 AND g.is_alone_sale = 1 AND g.is_delete = 0 $where $top10_time " ;
  42. //判断是否启用库存,库存数量是否大于0
  43. if ($GLOBALS['_CFG']['use_storage'] == 1)
  44. {
  45. $sql .= " AND g.goods_number > 0 ";
  46. }
  47. $sql .= ' AND og.order_id = o.order_id AND og.goods_id = g.goods_id ' .
  48. "AND (o.order_status = '" . OS_CONFIRMED . "' OR o.order_status = '" . OS_SPLITED . "') " .
  49. "AND (o.pay_status = '" . PS_PAYED . "' OR o.pay_status = '" . PS_PAYING . "') " .
  50. "AND (o.shipping_status = '" . SS_SHIPPED . "' OR o.shipping_status = '" . SS_RECEIVED . "') " .
  51. 'GROUP BY g.goods_id ORDER BY goods_number DESC, g.goods_id DESC LIMIT ' . $GLOBALS['_CFG']['top_number'];

  52. $arr = $GLOBALS['db']->getAll($sql);

  53. for ($i = 0, $count = count($arr); $i < $count; $i++)
  54. {
  55. $arr[$i]['short_name'] = $GLOBALS['_CFG']['goods_name_length'] > 0 ?
  56. sub_str($arr[$i]['goods_name'], $GLOBALS['_CFG']['goods_name_length']) : $arr[$i]['goods_name'];
  57. $arr[$i]['url'] = build_uri('goods', array('gid' => $arr[$i]['goods_id']), $arr[$i]['goods_name']);
  58. $arr[$i]['thumb'] = get_image_path($arr[$i]['goods_id'], $arr[$i]['goods_thumb'],true);
  59. $arr[$i]['price'] = price_format($arr[$i]['shop_price']);
  60. }
  61. $GLOBALS['db']->query('update '.$GLOBALS['ecs']->table('shop_config').' set value="'.date('Ymd').'" WHERE code="top10_check"');
  62. write_static_cache('top_10', $arr);
  63. }
  64. return $arr;
  65. }
复制代码






然后 在网站跟目下下 寻找 包含smarty->assign('top_goods',get_top10());
的php文件

网站首页 index.php
分类页category.php
品牌页brand.php
搜索页search.php 等等根目录下大约16个php文件都有调用,

找到
smarty->assign('top_goods',get_top10());

把这段东西都给注释掉
就是改成

/*smarty->assign('top_goods',get_top10());*/


现在cpu稳定在 20% 多了..

还在观察中..貌似稳定了.....继续观察一阵子看看

回答:
过来看看!




感谢支持 我貌似把问题解决了

去分析 get_top10
才是研究精神




我费了牛劲才找到这个问题

貌似确实稳定了

我只是把这个功能给屏蔽掉了

.... 优化 还没搞明白

不是加索引能解决的




这个属于ecshop 在性能上处理不当的地方.吧...

貌似你有独到的解决方法.看到网上只有你在解决这个问题

只能牺牲功能换去效率

同樣問題,試試

我使劲的顶一下,这个贴子太对帮助太大了。

这就是按照这个方法帮我度过难关的。




{:3_51:} {:3_51:}

明显的sql语句写的不够优化导致的,建议在sql 性能方面多学习优化。

太技术了这个我也刚好在研究,学习一下下!

先留着以后备用