自己搭建了一个基于SpringBoot+Spring Security+MyBatis+MySQL+Redis+Thymeleaf的博客网站
上线个人云服务器后,发现服务器访问慢。个人服务器是1核2G的,1M宽带,虽然服务器是低配的,但是可以通过优化代码,中间件等手段,来提升性能。
这篇主要讲数据库优化
数据库优化主要从两方面讲,索引优化,减少数据库的交互这两方面讲
索引优化
一、索引优化
article表的字段有这些,这个表存的文章的相关信息,包括主键id,文章id,作者,标题,文本内容,标签,发布时间,更新时间,上一篇文章id,下一篇文章id等等
当初设计表的时候,只有id一个主键,根据id查找该篇文章的信息。后期根据这篇文章的id,找到上一篇文章和下一篇文章的信息。这里经常会用到文章的id,所以id也要加个索引,加快查询的速度,当文章的数量越来越多时,索引的优点就会更加突显出来。
二、减少数据库交互
根据文章id查询一篇文章,查询出来,会把该文章的上一篇文章id(lastArticleId),查询上一篇文章信息来,会把该文章的下一篇文章id(nextArticleId),查询下一篇文章信息来。
service层
Article realArticle = articleMapper.findArticleByArticleId(article.getId());
if(realArticle != null) {
Article lastArticle = articleMapper.findArticleByArticleId(realArticle.getLastArticleId());
Article nextArticle = articleMapper.findArticleByArticleId(realArticle.getNextArticleId());
}
mapper层
@Select("select articleId,articleTitle from article where articleId=#{articleId}")
Article findArticleByArticleId(@Param("articleId") long articleId);
很明显,查询一篇文章信息,就要涉及到数据库的三次交互,减少数据库的交互,是为了减轻数据库的压力,为此,要优化sql语句,根据一篇文章id,除了查出该篇文章信息,还要查询出上一篇文章和下一篇文章信息。
public JSONObject getArticleByArticleId(long articleId, String username) {
// 通过文章id,拿到当前文章,上一篇文章,下一篇文章,减少与数据库的交互
List<Article> articleObject = articleMapper.getCurrentLastNextArticleByArticleId(articleId);
if (CollectionUtils.isEmpty(articleObject)) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("status", "500");
jsonObject.put("errorInfo", "获取文章信息失败");
logger.error("获取文章id " + articleId + " 失败");
return jsonObject;
}
Article currentArticle = new Article();
Article lastArticle = new Article();
Article nextArticle = new Article();
genArticle(articleObject, currentArticle, lastArticle, nextArticle);
return genJsonObject(articleId, username, currentArticle, lastArticle, nextArticle);
}
这是优化的sql语句
@Select("SELECT 1 AS category,a1.id,a1.articleId,a1.author,a1.originalAuthor,a1.articleTitle,a1.articleContent, " +
"a1.articleTags,a1.articleType,a1.articleCategories,a1.publishDate,a1.updateDate,a1.articleUrl, " +
"a1.articleTabloid,a1.likes,a1.lastArticleId,a1.nextArticleId " +
"FROM article a1 WHERE a1.articleId=#{articleId} " +
"UNION SELECT 2 AS category,a2.id,a2.articleId,a2.author,a2.originalAuthor,a2.articleTitle,a2.articleContent, " +
"a2.articleTags,a2.articleType,a2.articleCategories,a2.publishDate,a2.updateDate,a2.articleUrl, " +
"a2.articleTabloid,a2.likes,a2.lastArticleId,a2.nextArticleId " +
"FROM article a2 " +
" LEFT JOIN article a3 ON a2.articleId = a3.lastArticleId " +
" WHERE a3.articleId=#{articleId} " +
" UNION SELECT 3 AS category,a4.id,a4.articleId,a4.author,a4.originalAuthor,a4.articleTitle,a4.articleContent, " +
"a4.articleTags,a4.articleType,a4.articleCategories,a4.publishDate,a4.updateDate,a4.articleUrl, " +
"a4.articleTabloid,a4.likes,a4.lastArticleId,a4.nextArticleId " +
"FROM article a4 " +
" LEFT JOIN article a5 ON a4.articleId = a5.nextArticleId " +
" WHERE a5.articleId=#{articleId}")
List<Article> getCurrentLastNextArticleByArticleId(@Param("articleId") long articleId);
相比之前的sql语句,长了很多,但是减少了跟数据库的交互,一篇文章与数据库交互3次,当数目越多,数据库压力越大。
总结:数据库优化方面,从索引,从sql语句优化,减少与数据库的交互