刚上线的 PHP 网站,刚开始用户少的时候跑得飞快,可用户一多就卡得不行?刷新页面要等好几秒,数据库查询半天没反应,用户都跑光了。其实啊,这不是服务器不够好,很多时候是没做好性能优化。今天兔子哥就带新手朋友搞定两个核心优化点 —— 缓存机制和数据库索引,都是实战中能立竿见影的方法,看完你也能让网站快起来!
一、先明白:为啥网站会变慢?
估计有新手会问:“我写的代码挺简单的,怎么就慢了?” 网站慢主要就两个原因:要么是数据库查询太费劲,要么是重复计算太多。比如一个商品列表页,每次打开都去数据库查一遍,数据多了自然慢;或者首页轮播图,每个用户打开都重新生成一次,纯属浪费资源。
性能优化就像给网站 “减负”:让常用数据不用每次都查数据库,让数据库查询少走弯路。这就是缓存和索引的作用,简单说 —— 缓存是 “把常用数据存起来,下次直接用”,索引是 “给数据库指条明路,快速找到数据”。
二、缓存机制:让数据 “少跑腿”
缓存说白了就是 “临时仓库”,把频繁用到但不常变的数据存进去,用户再要的时候直接从仓库拿,不用再去数据库 “进货”,速度自然快。
1. 新手先学文件缓存:简单又实用
对新手来说,不用一上来就搞复杂的缓存工具,PHP 自带的文件操作就能做简单缓存。比如商品分类列表,一天才更新一次,完全可以缓存起来。
详细的设置方法,一起看看吧:
php
// 获取商品分类(带缓存)function getCategories() {$cacheFile = 'cache/categories.php'; // 缓存文件路径$cacheTime = 3600; // 缓存时间,3600秒=1小时// 检查缓存文件是否存在且没过期if (file_exists($cacheFile) && time() - filemtime($cacheFile) < $cacheTime) {// 从缓存拿数据return unserialize(file_get_contents($cacheFile));}// 缓存过期或不存在,查数据库$categories = Db::name('category')->select();// 存到缓存文件file_put_contents($cacheFile, serialize($categories));return $categories;}这样设置后,1 小时内不管多少用户访问,都只查一次数据库,服务器压力一下就降下来了。记得建个 cache 文件夹,给写权限,不然存不了缓存文件。
2. 进阶用 Redis:速度更快还支持多种数据类型
如果网站访问量更大,文件缓存就不够用了,这时候可以用 Redis。它是专门的缓存工具,存在内存里,比文件缓存快得多。
新手用 Redis 不用学太复杂,先会这几个操作就行:
- 连接 Redis:
$redis = new Redis(); $redis->connect('127.0.0.1', 6379); - 存数据:
$redis->set('key', 'value', 3600);// 3600 秒过期 - 取数据:
$redis->get('key'); - 删数据:
$redis->del('key');
比如缓存用户信息:
php
// 用Redis缓存用户信息function getUser($userId) {$redis = new Redis();$redis->connect('127.0.0.1', 6379);$key = 'user_' . $userId;// 先查缓存$user = $redis->get($key);if ($user) {return json_decode($user, true);}// 缓存没命中,查数据库$user = Db::name('user')->where('id', $userId)->find();// 存到Redis,设置2小时过期$redis->set($key, json_encode($user), 7200);return $user;}Redis 比文件缓存快 5-10 倍,适合用户信息、热门商品这些高频访问的数据。不过新手刚开始可以先用文件缓存练手,熟练了再上 Redis。
三、数据库索引:给查询 “开绿灯”
数据库就像一本大字典,没索引想查个数据得从头到尾翻,有了索引直接按目录找,速度天差地别。但很多新手要么不会建索引,要么乱建一通,反而变慢。
1. 啥字段该建索引?这几个场景必须加
不是所有字段都适合建索引,这几种情况一定要加,不然查询会很慢:
- 经常出现在 WHERE 条件里的字段,比如
where user_id=1里的 user_id - 用来排序的字段,比如
order by create_time里的 create_time - 用来关联表的字段,比如订单表的 user_id 关联用户表
比如用户表查手机号登录,给 phone 字段建索引:
sql
-- 给phone字段建索引CREATE INDEX idx_user_phone ON user(phone);建了索引后,查
where phone='13800138000'的速度能从 0.5 秒降到 0.01 秒,快 50 倍!2. 哪些情况别建索引?建了反而添乱
索引不是越多越好,这几种情况建了索引反而变慢:
- 表数据太少(比如不到 1000 条),建索引浪费空间
- 经常更新的字段,比如订单状态,每次更新都要维护索引,反而慢
- 重复值多的字段,比如性别(只有男 / 女),建索引效果不大
之前有个朋友给订单表的 status 字段建了索引,结果订单量一大,更新状态时数据库卡得不行,删掉索引后反而快了。所以索引要 “按需建”,别盲目加。
3. 怎么知道索引有没有生效?
建了索引不一定就会被用到,新手可以用 EXPLAIN 命令检查:
sql
-- 检查索引是否生效EXPLAIN SELECT * FROM goods WHERE category_id=5;看结果里的 “key” 列,如果显示你建的索引名,说明生效了;如果是 NULL,说明没用到,得检查索引建得对不对,或者 SQL 写得有问题。
四、新手常踩的坑:这些错误让优化白费劲
1. 缓存没及时更新,用户看到旧数据
有朋友缓存了商品价格,结果改了价格后没清缓存,用户看到的还是旧价格,投诉一堆。解决办法是更新数据后手动清缓存:
php
// 更新商品后清缓存function updateGoods($id, $data) {// 更新数据库Db::name('goods')->where('id', $id)->update($data);// 清缓存$cacheFile = 'cache/goods_' . $id . '.php';if (file_exists($cacheFile)) {unlink($cacheFile);}}这样用户下次访问就会查新数据,再存新缓存。
2. 索引字段用函数处理,导致索引失效
比如想查手机号以 138 开头的用户,这么写索引会失效:
sql
-- 错误写法:索引失效SELECT * FROM user WHERE SUBSTR(phone, 1, 3) = '138';应该写成:
sql
-- 正确写法:索引生效SELECT * FROM user WHERE phone LIKE '138%';索引字段别用函数、别加运算,不然数据库认不出,只能全表扫描。
五、兔子哥的优化心得
做性能优化这几年,我发现新手最容易犯的错是 “过度优化” 或 “不优化”。其实优化要循序渐进:
- 先解决明显的慢查询,用 EXPLAIN 找出没索引的 SQL,加上索引就能快很多
- 再用缓存,先从简单的文件缓存开始,数据量大了再上 Redis
- 定期检测,用 PHP 的 microtime () 函数测代码执行时间,找出慢的地方针对性优化
之前帮一个朋友优化博客网站,就加了两个索引,用文件缓存了分类列表,页面加载时间从 3 秒降到了 0.3 秒,用户体验立马上去了。所以优化不用多复杂,找对关键点就行。
记住,性能优化不是一次性的事,网站变大后要定期看慢查询日志,调整缓存策略。新手不用怕,从简单的开始,慢慢积累经验,你的网站也能跑得飞快!
标签: categories.php' getCategories
版权声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。
还木有评论哦,快来抢沙发吧~