PHP查询语句怎么提升速度_PHP索引优化查询性能指南【指南】

2次阅读

mysql查询慢的主因是where字段无索引导致全表扫描,应建普通或联合索引;like ‘%xxx’使索引失效,需改用’xxx%’或全文索引;避免select*、n+1查询及order by/group by无索引。

PHP查询语句怎么提升速度_PHP索引优化查询性能指南【指南】

WHERE 条件字段没加索引,查得慢是必然的

MySQL 在执行 SELECT 时,如果 WHERE 中的字段没索引,就会全表扫描。哪怕只有几千行,有 JOIN 或 ORDER BY 时响应也会明显卡顿。

实操建议:

  • EXPLAIN SELECT ...type 是否为 ALL(全表扫描),key 列是否为 NULL
  • 对高频查询条件字段建普通索引,例如用户登录查 usernameemail,就执行:
    ALTER TABLE `users` ADD INDEX idx_username (`username`);
  • 复合查询优先建联合索引,比如常查 status = 1 AND created_at > '2024-01-01',建 INDEX idx_status_created (status, created_at),顺序不能颠倒——等值条件字段放前面,范围条件放后面

php 中拼接 SQL 时用了 LIKE ‘%xxx’,索引直接失效

前导通配符(如 LIKE '%abc')会让 MySQL 放弃使用索引,哪怕字段本身有索引。

常见场景:搜索框模糊匹配用户昵称、商品标题。

立即学习PHP免费学习笔记(深入)”;

解决方向:

  • 改用 LIKE 'abc%'(后缀通配),索引仍可生效
  • 需要前后模糊?考虑引入 fulltext 索引 + MATCH ... AGAINST,但仅限 MyISAMInnoDB(5.6+),且需调整最小词长
  • 更重的搜索需求(如高亮、拼音、分词),别硬扛在 MySQL 里,换 elasticsearchsphinx

PHP 查询中用了 SELECT *,IO 和网络开销白增一倍

尤其当表有 TEXT、BLOB 字段,或 JOIN 多张宽表时,SELECT * 会把不需要的字段也从磁盘读出、经网络传给 PHP,既拖慢 MySQL,又加重 PHP 内存压力。

正确做法:

  • 明确写出需要的字段,例如:SELECT id, title, status FROM posts WHERE ...
  • 避免在循环里查同一条记录多次(N+1 问题),用 JOIN 或一次性 IN 查询预加载,比如查 10 篇文章的作者名,别 for 循环 10 次 SELECT name FROM users WHERE id = ?
  • 大字段(如 content)单独拆表或延迟加载,主列表页不查,详情页再按需 SELECT content FROM posts_ext WHERE post_id = ?

ORDER BY 和 GROUP BY 没走索引,临时表+文件排序拖垮性能

ORDER BY 字段没索引,或和 WHERE 条件不构成最左前缀时,MySQL 会创建 using filesortGROUP BY 同理,可能触发 Using temporary —— 这两种都意味着额外磁盘 IO 和内存消耗。

检查与优化:

  • EXPLAIN 输出里看 Extra 列是否含 Using filesortUsing temporary
  • ORDER BY a, b 要走索引,就得有 INDEX(a, b);如果还带 WHERE c = ?,那联合索引得是 INDEX(c, a, b) 才能覆盖
  • 避免在排序字段上用函数,例如 ORDER BY UPPER(name) 会让索引失效;如必须大小写不敏感,建生成列索引:
    ALTER TABLE users ADD COLUMN name_lower VARCHAR(255) STORED AS (LOWER(name)); CREATE INDEX idx_name_lower ON users(name_lower);

索引不是越多越好,写多读少的表加太多索引反而拖慢 INSERT/UPDATE;真正关键的是理解查询模式,再用 EXPLAIN 验证每条慢 SQL 的执行路径。很多“慢”其实发生在 PHP 层没复用 pdo 预处理、或一次查了 500 行却只显示 10 条这种地方。

text=ZqhQzanResources