18条优化Laravel 数据库查询的建议(10-12)
10. 为频繁查询字段添加索引
如果你通过对字符串性字段使用where条件,最好为该字段添加索引。带有索引的字段查询通常会快许多。
$posts = Post::where('status','=','published')->get();
上例我们给status添加了where条件查询记录。我们可以在数据库migration中添加index索引改进性能:
Schema::table('posts', function (Blueprint $table) {
$table->index('status');
});
11. 使用简单分页代替 Paginate
我们通常这样分页:
$posts = Post::paginate(20);
这会产生两个查询,一个查询分页结果,一个计算表中总记录数。计算行数是个慢操作,会对查询性能产生副作用。
为什么Laravel要计算总行数呢?
为了生成分页链接。因此当分页链接生成后,你可以事先知道总共有多少页以及最后一页的数字。你可以导航到任意你想去的页面。
如果使用simplePaginate, 不会计算总行数,查询会比paginate快很多。不过你也因此不能知道总页数,没办法跳到任意页。
如果你的数据库有太多数据,最好使用simplePaginate, 避免使用paginate.
$posts = Post::paginate(20); // Generates pagination links for all the pages
$posts = Post::simplePaginate(20); // Generates only next and previous pagination links
何时使用 paginate 或者 simple paginate?
以下简单的对比作为参考:
paginate / simplePaginate | |
---|---|
数据库表只有几行且增长不快 | paginate / simplePaginate |
数据库表有很多行且增长很快 | simplePaginate |
需要让用户可以跳转到指定页面 | paginate |
需要将总行数显示给用户 | paginate |
没有使用分页链接 | simplePaginate |
UI/UX 从数字分页链接切换到 上一页/下一页 链接没有影响 | simplePaginate |
使用load more按钮或者上拉下拉加载分页数据 | simplePaginate |
12. 避免使用前缀通配符(LIKE 关键字)
当查询特定的模式匹配结果的时候,我们通常会这样:
select * from table_name where column like %keyword%
以上查询会导致全表扫描,如果我们知道这个字段前面的值,我们可以这样:
select * from table_name where column like keyword%