如果ECshop的商品数达到几万,十几万的时候,如果首页没有缓存,第一次访问的时候,你会发现其慢无比,原因就是清空了Cache后或者没有Cache的情况下,ECshop会Bulid一些Cache数据,导致访问很慢,但我们有时候后台编辑类目或者其他的,经常会触发清空Cache,所以首页首次访问也成了问题。

在大数据量的情况下,影响首页速度最大的就是推荐的Best、Hot、New Item的数据Bulid,它会把所有的复合条件的商品都会读一遍,然后存到/temp/static_caches /recommend_goods.php这个文件下,有时候会达到10M或者数十M,其实我们并不需要所有的商品都Bulid进去,因为这个缓存只用在 首页和Category页的调用,有点浪费。(P.S 因为Category访问本来就比较慢,所以我把热卖商品在Category的展示屏蔽了,所以只剩首页调用)

首页展示的时候,三种类型Best、Hot、New只展示10个商品(我没有选择展示多个类目),所以这个上面有很大的优化空间。

打开include目录下的lib_goods.php文件,找到function get_recommend_goods() 函数,原始的大概是:

  1. function get_recommend_goods($type = '', $cats = '')
  2. {
  3. if (!in_array($type, array('best', 'new', 'hot')))
  4. {
  5. return array();
  6. }
  7.  
  8. //取不同推荐对应的商品
  9. static $type_goods = array();
  10. if (empty($type_goods[$type]))
  11. {
  12. //初始化数据
  13. $type_goods['best'] = array();
  14. $type_goods['new'] = array();
  15. $type_goods['hot'] = array();
  16. $data = read_static_cache('recommend_goods');
  17. if ($data === false)
  18. {
  19. $sql = 'SELECT g.goods_id, g.is_best, g.is_new, g.is_hot, g.is_promote, b.brand_name,g.sort_order ' .
  20. ' FROM ' . $GLOBALS['ecs']->table('goods') . ' AS g ' .
  21. ' LEFT JOIN ' . $GLOBALS['ecs']->table('brand') . ' AS b ON b.brand_id = g.brand_id ' .
  22. ' WHERE g.is_on_sale = 1 AND g.is_alone_sale = 1 AND g.is_delete = 0 AND (g.is_best = 1 OR g.is_new =1 OR g.is_hot = 1)'.
  23. ' ORDER BY g.sort_order, g.last_update DESC';
  24. $goods_res = $GLOBALS['db']->getAll($sql);
  25. //定义推荐,最新,热门,促销商品
  26. $goods_data['best'] = array();
  27. $goods_data['new'] = array();
  28. $goods_data['hot'] = array();
  29. $goods_data['brand'] = array();
  30. if (!empty($goods_res))
  31. {
  32. foreach($goods_res as $data)
  33. {
  34. if ($data['is_best'] == 1)
  35. {
  36. $goods_data['best'][] = array('goods_id' => $data['goods_id'], 'sort_order' => $data['sort_order']);
  37. }
  38. if ($data['is_new'] == 1)
  39. {
  40. $goods_data['new'][] = array('goods_id' => $data['goods_id'], 'sort_order' => $data['sort_order']);
  41. }
  42. if ($data['is_hot'] == 1)
  43. {
  44. $goods_data['hot'][] = array('goods_id' => $data['goods_id'], 'sort_order' => $data['sort_order']);
  45. }
  46. if ($data['brand_name'] != '')
  47. {
  48. $goods_data['brand'][$data['goods_id']] = $data['brand_name'];
  49. }
  50. }
  51. }
  52. write_static_cache('recommend_goods', $goods_data);
  53. }
  54. else
  55. {
  56. $goods_data = $data;
  57. }
  58.  
  59. $time = gmtime();
  60. $order_type = $GLOBALS['_CFG']['recommend_order'];
  61.  
  62. //按推荐数量及排序取每一项推荐显示的商品 order_type可以根据后台设定进行各种条件显示
  63. static $type_array = array();
  64. $type2lib = array('best'=>'recommend_best', 'new'=>'recommend_new', 'hot'=>'recommend_hot');
  65. if (empty($type_array))
  66. {
  67. foreach($type2lib as $key => $data)
  68. {
  69. if (!empty($goods_data[$key]))
  70. {
  71. $num = get_library_number($data);
  72. $data_count = count($goods_data[$key]);
  73. $num = $data_count > $num ? $num : $data_count;
  74. if ($order_type == 0)
  75. {
  76. //usort($goods_data[$key], 'goods_sort');
  77. $rand_key = array_slice($goods_data[$key], 0, $num);
  78. foreach($rand_key as $key_data)
  79. {
  80. $type_array[$key][] = $key_data['goods_id'];
  81. }
  82. }
  83. else
  84. {
  85. $rand_key = array_rand($goods_data[$key], $num);
  86. if ($num == 1)
  87. {
  88. $type_array[$key][] = $goods_data[$key][$rand_key]['goods_id'];
  89. }
  90. else
  91. {
  92. foreach($rand_key as $key_data)
  93. {
  94. $type_array[$key][] = $goods_data[$key][$key_data]['goods_id'];
  95. }
  96. }
  97. }
  98. }
  99. else
  100. {
  101. $type_array[$key] = array();
  102. }
  103. }
  104. }
  105.  
  106. //取出所有符合条件的商品数据,并将结果存入对应的推荐类型数组中
  107. $sql = 'SELECT g.goods_id, g.goods_name, g.goods_name_style, g.market_price, g.shop_price AS org_price, g.promote_price, ' .
  108. "IFNULL(mp.user_price, g.shop_price * '$_SESSION[discount]') AS shop_price, ".
  109. "promote_start_date, promote_end_date, g.goods_brief, g.goods_thumb, g.goods_img, RAND() AS rnd " .
  110. 'FROM ' . $GLOBALS['ecs']->table('goods') . ' AS g ' .
  111. "LEFT JOIN " . $GLOBALS['ecs']->table('member_price') . " AS mp ".
  112. "ON mp.goods_id = g.goods_id AND mp.user_rank = '$_SESSION[user_rank]' ";
  113. $type_merge = array_merge($type_array['new'], $type_array['best'], $type_array['hot']);
  114. $type_merge = array_unique($type_merge);
  115. $sql .= ' WHERE g.goods_id ' . db_create_in($type_merge);
  116. $sql .= ' ORDER BY g.sort_order, g.last_update DESC';
  117.  
  118. $result = $GLOBALS['db']->getAll($sql);
  119. foreach ($result AS $idx => $row)
  120. {
  121. if ($row['promote_price'] > 0)
  122. {
  123. $promote_price = bargain_price($row['promote_price'], $row['promote_start_date'], $row['promote_end_date']);
  124. $goods[$idx]['promote_price'] = $promote_price > 0 ? price_format($promote_price) : '';
  125. }
  126. else
  127. {
  128. $goods[$idx]['promote_price'] = '';
  129. }
  130.  
  131. $goods[$idx]['id'] = $row['goods_id'];
  132. $goods[$idx]['name'] = $row['goods_name'];
  133. $goods[$idx]['brief'] = $row['goods_brief'];
  134. $goods[$idx]['brand_name'] = isset($goods_data['brand'][$row['goods_id']]) ? $goods_data['brand'][$row['goods_id']] : '';
  135. $goods[$idx]['goods_style_name'] = add_style($row['goods_name'],$row['goods_name_style']);
  136.  
  137. $goods[$idx]['short_name'] = $GLOBALS['_CFG']['goods_name_length'] > 0 ?
  138. sub_str($row['goods_name'], $GLOBALS['_CFG']['goods_name_length']) : $row['goods_name'];
  139. $goods[$idx]['short_style_name'] = add_style($goods[$idx]['short_name'],$row['goods_name_style']);
  140. $goods[$idx]['market_price'] = price_format($row['market_price']);
  141. $goods[$idx]['shop_price'] = price_format($row['shop_price']);
  142. $goods[$idx]['thumb'] = get_image_path($row['goods_id'], $row['goods_thumb'], true);
  143. $goods[$idx]['goods_img'] = get_image_path($row['goods_id'], $row['goods_img']);
  144. $goods[$idx]['url'] = build_uri('goods', array('gid' => $row['goods_id']), $row['goods_name']);
  145. if (in_array($row['goods_id'], $type_array['best']))
  146. {
  147. $type_goods['best'][] = $goods[$idx];
  148. }
  149. if (in_array($row['goods_id'], $type_array['new']))
  150. {
  151. $type_goods['new'][] = $goods[$idx];
  152. }
  153. if (in_array($row['goods_id'], $type_array['hot']))
  154. {
  155. $type_goods['hot'][] = $goods[$idx];
  156. }
  157. }
  158. }
  159. return $type_goods[$type];
  160. }

我的思路就是不读取所有的商品信息,而是Best、Hot、New够用展示就行了,所以把代码调整了一下,限制了Bulid的商品数,去掉了一些我不需要的Join表,当然大家不一定要照着我做,我讲的都是思路,看自己的实际情况,要有点程序基本功。

更改后的代码如下:

  1. function get_recommend_goods($type = '', $cats = '')
  2. {
  3. if (!in_array($type, array('best', 'new', 'hot')))
  4. {
  5. return array();
  6. }
  7.  
  8. //取不同推荐对应的商品
  9. static $type_goods = array();
  10. if (empty($type_goods[$type]))
  11. {
  12. //初始化数据
  13. $type_goods['best'] = array();
  14. $type_goods['new'] = array();
  15. $type_goods['hot'] = array();
  16. $data = read_static_cache('recommend_goods');
  17. if ($data === false)
  18. {
  19. $sql = 'SELECT g.goods_id, g.sort_order ' .
  20. ' FROM ' . $GLOBALS['ecs']->table('goods') . ' AS g ' .
  21. ' WHERE (g.is_best = 1)'.
  22. ' ORDER BY g.goods_number DESC limit 50';
  23. $goods_res = $GLOBALS['db']->getAll($sql);
  24. $goods_data['best'] = array();
  25.  
  26. if (!empty($goods_res))
  27. {
  28. foreach($goods_res as $data)
  29. {
  30. $goods_data['best'][] = array('goods_id' => $data['goods_id'], 'sort_order' => $data['sort_order']);
  31. }
  32. }
  33.  
  34. $sql = 'SELECT g.goods_id, g.sort_order ' .
  35. ' FROM ' . $GLOBALS['ecs']->table('goods') . ' AS g ' .
  36. ' WHERE (g.is_new = 1 and g.is_best = 0 and g.is_hot = 0)'.
  37. ' ORDER BY g.goods_id DESC limit 50';
  38. $goods_res = $GLOBALS['db']->getAll($sql);
  39. $goods_data['new'] = array();
  40.  
  41. if (!empty($goods_res))
  42. {
  43. foreach($goods_res as $data)
  44. {
  45. $goods_data['new'][] = array('goods_id' => $data['goods_id'], 'sort_order' => $data['sort_order']);
  46. }
  47. }
  48.  
  49. $sql = 'SELECT g.goods_id, g.sort_order ' .
  50. ' FROM ' . $GLOBALS['ecs']->table('goods') . ' AS g ' .
  51. ' WHERE (g.is_hot = 1 and g.is_best = 0)'.
  52. ' ORDER BY g.goods_number DESC limit 50';
  53. $goods_res = $GLOBALS['db']->getAll($sql);
  54. $goods_data['hot'] = array();
  55.  
  56. if (!empty($goods_res))
  57. {
  58. foreach($goods_res as $data)
  59. {
  60. $goods_data['hot'][] = array('goods_id' => $data['goods_id'], 'sort_order' => $data['sort_order']);
  61. }
  62. }
  63.  
  64. write_static_cache('recommend_goods', $goods_data);
  65. }
  66. else
  67. {
  68. $goods_data = $data;
  69. }
  70.  
  71. $time = gmtime();
  72. $order_type = $GLOBALS['_CFG']['recommend_order'];
  73.  
  74. //按推荐数量及排序取每一项推荐显示的商品 order_type可以根据后台设定进行各种条件显示
  75. static $type_array = array();
  76. $type2lib = array('best'=>'recommend_best', 'new'=>'recommend_new', 'hot'=>'recommend_hot');
  77. if (empty($type_array))
  78. {
  79. foreach($type2lib as $key => $data)
  80. {
  81. if (!empty($goods_data[$key]))
  82. {
  83. $num = get_library_number($data);
  84. $data_count = count($goods_data[$key]);
  85. $num = $data_count > $num ? $num : $data_count;
  86. if ($order_type == 0)
  87. {
  88. //usort($goods_data[$key], 'goods_sort');
  89. $rand_key = array_slice($goods_data[$key], 0, $num);
  90. foreach($rand_key as $key_data)
  91. {
  92. $type_array[$key][] = $key_data['goods_id'];
  93. }
  94. }
  95. else
  96. {
  97. $rand_key = array_rand($goods_data[$key], $num);
  98. if ($num == 1)
  99. {
  100. $type_array[$key][] = $goods_data[$key][$rand_key]['goods_id'];
  101. }
  102. else
  103. {
  104. foreach($rand_key as $key_data)
  105. {
  106. $type_array[$key][] = $goods_data[$key][$key_data]['goods_id'];
  107. }
  108. }
  109. }
  110. }
  111. else
  112. {
  113. $type_array[$key] = array();
  114. }
  115. }
  116. }
  117.  
  118. //取出所有符合条件的商品数据,并将结果存入对应的推荐类型数组中
  119. $sql = 'SELECT g.goods_id, g.goods_name, g.goods_name_style, g.market_price, g.shop_price AS org_price, g.promote_price, g.shop_price, ' .
  120. "promote_start_date, promote_end_date, g.goods_brief, g.goods_thumb, g.goods_img, RAND() AS rnd " .
  121. 'FROM ' . $GLOBALS['ecs']->table('goods') . ' AS g ' .
  122. " ";
  123. $type_merge = array_merge($type_array['new'], $type_array['best'], $type_array['hot']);
  124. $type_merge = array_unique($type_merge);
  125. $sql .= ' WHERE g.goods_id ' . db_create_in($type_merge);
  126. $sql .= ' ORDER BY g.goods_number DESC';
  127.  
  128. $result = $GLOBALS['db']->getAll($sql);
  129. foreach ($result AS $idx => $row)
  130. {
  131. if ($row['promote_price'] > 0)
  132. {
  133. $promote_price = bargain_price($row['promote_price'], $row['promote_start_date'], $row['promote_end_date']);
  134. $goods[$idx]['promote_price'] = $promote_price > 0 ? price_format($promote_price) : '';
  135. }
  136. else
  137. {
  138. $goods[$idx]['promote_price'] = '';
  139. }
  140.  
  141. $goods[$idx]['id'] = $row['goods_id'];
  142. $goods[$idx]['name'] = $row['goods_name'];
  143. $goods[$idx]['brief'] = $row['goods_brief'];
  144. $goods[$idx]['brand_name'] = isset($goods_data['brand'][$row['goods_id']]) ? $goods_data['brand'][$row['goods_id']] : '';
  145. $goods[$idx]['goods_style_name'] = add_style($row['goods_name'],$row['goods_name_style']);
  146.  
  147. $goods[$idx]['short_name'] = $GLOBALS['_CFG']['goods_name_length'] > 0 ?
  148. sub_str($row['goods_name'], $GLOBALS['_CFG']['goods_name_length']) : $row['goods_name'];
  149. $goods[$idx]['short_style_name'] = add_style($goods[$idx]['short_name'],$row['goods_name_style']);
  150. $goods[$idx]['market_price'] = price_format($row['market_price']);
  151. $goods[$idx]['shop_price'] = price_format($row['shop_price']);
  152. $goods[$idx]['thumb'] = get_image_path($row['goods_id'], $row['goods_thumb'], true);
  153. $goods[$idx]['goods_img'] = get_image_path($row['goods_id'], $row['goods_img']);
  154. $goods[$idx]['url'] = build_uri('goods', array('gid' => $row['goods_id']), $row['goods_name']);
  155. if (in_array($row['goods_id'], $type_array['best']))
  156. {
  157. $type_goods['best'][] = $goods[$idx];
  158. }
  159. if (in_array($row['goods_id'], $type_array['new']))
  160. {
  161. $type_goods['new'][] = $goods[$idx];
  162. }
  163. if (in_array($row['goods_id'], $type_array['hot']))
  164. {
  165. $type_goods['hot'][] = $goods[$idx];
  166. }
  167. }
  168. }
  169. return $type_goods[$type];
  170. }

这样改了以后,Bulid的静态文件应该只有13K左右,速度大大加快。

转载:http://blog.sina.com.cn/s/blog_70ea94110101h5d3.html

ECshop网店系统百万级商品量性能优化-加快首页访问速度的更多相关文章

  1. ECshop网店系统百万级商品量性能优化-简单的一些Cache内存配置

    ECshop网店系统对于产品的数据.模板.Query都可以缓存,也就是把一些商品详情页.分类页.Search页的数据经过一次访问后,用文件的形式保存下来,下次有人访问相同的页面时,不用再查数据库,直接 ...

  2. 让Ecshop网店系统用户自动登陆

    让Ecshop网店系统用户户自动登陆,打开ecshop includes/init.php文件,可以发现Ecshop系统判断用户的SESSION不存在的时候会去读取存储在COOKIES里面的值.如下代 ...

  3. DBShop 电子商务网店系统

    DBShop 电子商务网店系统,采用业界知名框架 ZendFramework 2 开发而成. 下面为功能简介 1.在线更新:在线系统更新和在线模板安装与更新,简单.方便.快捷,省却了手动更新的繁琐步骤 ...

  4. 《开源网店系统iWebShop2.0模板开发教程》的说明

    <开源网店系统iWebShop2.0模板开发教程>是网上广为流传的一个文档,有点问题. 其中的第4章: ========================================== ...

  5. 10款PHP开源网店系统

    在当今经济危机的大环境下,网上购物越来越来吃香,网上开店成本低,快捷方便,出名的电子商务网站有淘宝,拍拍,Ebay或是最新的百度有啊,这些网站都提供开店的机会,如果是想自己搭建购物平台,可以从下面选择 ...

  6. 海盗(Haidao)网店系统最新官方版

    产品介绍:经过开发团队半个月的努力,Haidao v1.1 beta版终于和大家见面了,在这个版本中我们重点系统目录结构和整体框架进行了改进,同时新增加了多个功能模块. 四大功能模块意在打造最灵活的电 ...

  7. 亿级 Elasticsearch 性能优化

    前言 最近一年使用 Elasticsearch 完成亿级别日志搜索平台「ELK」,亿级别的分布式跟踪系统.在设计这些系统的过程中,底层都是采用 Elasticsearch 来做数据的存储,并且数据量都 ...

  8. Spark难道比oracle性能还差?百万级数据测试性能

    本人对大数据方面也是刚刚研究,由于工作需要在实时查询与统计的性能方面要深入学习.现测试性能如下:   环境:VirtualBox  host-only ubuntu版本: Linux master 4 ...

  9. 设置ecShop网店用户名和email均可登录

    修改user.php文件,如果您网站的该文件修改过,按照下面的修改说明修改文件. 查找代码:elseif ($action == 'act_login') 在:$back_act = isset($_ ...

随机推荐

  1. 05---JSON学习(Java)

    一.简介         JSON:JavaScript对象表示法(JavaScript object Notation)         JSON是存储和文本交换信息的语法         JSON ...

  2. air 中的 LocalStore

    <ignore_js_op> 在AIR客户端程序中有时需要将用户的一些信息保存在本地,如果信息没有涉及到隐私那么一般用SharedObject类即可将数据存储在本地.由于SharedObj ...

  3. 文件I/O(不带缓冲)之open函数

    调用open函数可以打开或创建一个文件. #include <fcntl.h> int open( const char *pathname, int oflag, ... /* mode ...

  4. mac中vmware tools进行磁盘压缩和vmware-tools-cli的使用方法

    前言: 高高兴兴的在vmware9.0中安装了mac10.8系统,然后学习iphone开发,但是发现下载的pdf都是基于xcode3.2.5的,又在10.8上面安装3.2.5,出现“五国”无法解决,最 ...

  5. 配置SQL Server 2008管理器

    SQl Server 配置管理器(简称为配置管理器)包含了SQL Server 2008服务.SQL Server 2008网络配置和SQL Native Client配置3个工具,供数据库管理人员做 ...

  6. java_泛型方法使用实例

    //提供两种使用情况,第二种情况定义前者是后者的子类-类型通配方式 package ming; import java.util.ArrayList; import java.util.Collect ...

  7. View绘制详解,从LayoutInflater谈起

    自定义View算是Android开发中的重中之重了,很多小伙伴可能或多或少都玩过自定义View,对View的绘制流程也有一定的理解.那么现在我想通过几篇博客来详细介绍View的绘制流程,以便使我们更加 ...

  8. 16% off MPPS V16 ECU tuning tool for EDC15 EDC16 EDC17

    EOBD2.FR is offering 16% discount off the latest MPPS V16 ECU chip tuning tool. The device is now so ...

  9. javascript笔记07:使用Object类为实例定义方法和属性

    function Person() {} Person.prototype = { nickName:"john", , showInfo:function() { return ...

  10. 【转】SQL Server 2012 配置AlwaysOn(三)

    转载自:http://www.cnblogs.com/lyhabc/p/4682986.html 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http:/ ...