自己搭建了一个基于SpringBoot+Spring Security+MyBatis+MySQL+Redis+Thymeleaf的博客网站
上线个人云服务器后,发现服务器访问慢。个人服务器是1核2G的,1M宽带,虽然服务器是低配的,但是可以通过优化代码,中间件等手段,来提升性能。

这篇主要讲数据库优化

数据库优化主要从两方面讲,索引优化,减少数据库的交互这两方面讲
索引优化

一、索引优化

article表的字段有这些,这个表存的文章的相关信息,包括主键id,文章id,作者,标题,文本内容,标签,发布时间,更新时间,上一篇文章id,下一篇文章id等等
个人网站性能优化经历(3)加索引,减少数据库交互_性能优化
当初设计表的时候,只有id一个主键,根据id查找该篇文章的信息。后期根据这篇文章的id,找到上一篇文章和下一篇文章的信息。这里经常会用到文章的id,所以id也要加个索引,加快查询的速度,当文章的数量越来越多时,索引的优点就会更加突显出来。
个人网站性能优化经历(3)加索引,减少数据库交互_json_02

二、减少数据库交互

根据文章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语句优化,减少与数据库的交互