• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > MySQL性能优化 出题业务SQL优化

MySQL性能优化 出题业务SQL优化

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-11

通过本文主要向大家介绍了mysql性能优化,mysql高性能优化,mysql数据库性能优化,mysql性能优化总结,mysql sql性能优化等相关知识,希望本文的分享对您有所帮助

先简单介绍一下项目背景。这是一个在线考试练习平台,数据库使用MySQL,表结构如图所示:

Question是存储题目的表,数据量在3万左右。AnswerResult表是存储用户作答结果的表,分表之后单表记录大概在300万-400万。

需求:根据用户的作答结果出练习卷,题目的优先级为:未做过的题目>只做错的题目>做错又做对的题目>只做对的题目。

在“做错又做对的题目”中,会按错误次数和正确次数的比例进行权重计算,比如:A、做错10次,做对100次;B、做错10次,做对20次。这时B被选中出给用户练习的概率就大。

备注:AnswerResult表中不存在QuestionId的记录,则代表该题没有做过。

之前使用的方法:

  SELECT Question.题目标识,IFNULL((0-正确次数)/(正确次数+错误次数),1) AS 权重 FROM Question

  LEFT JOIN AnswerResult ON AnswerResult.题目标识 = Question.题目标识

  WHERE 用户标识={UserId}

说明:IFNULL((0-正确次数)/(正确次数+错误次数),1)这个函数式分2部分,

公式:(0-正确次数)/(正确次数+错误次数)得到题目的权重,这个区间为[0,-1],0表示只做错的题目,-1表示只做对的题目。IFNULL(value,1)则将未做过的题目权重设置为1,根据这个权重进行排序列出题目。

由于AnswerResult表是多达300、400百万的表,所以通过LEFT JOIN进行左连接时,迪卡尔乘积过大,又加上AnswerResult是频繁读写的表,很容易导致这条SQL变成慢查询。

性能问题被提上日程后,这条SQL语句就变成的优化点。

1、IFNULL()这个函数计算可以调整成冗余字段。

2、LEFT JOIN的迪卡尔乘积太大,可以调整为冗余或者使用INNER JOIN以提高查询速度。

3、根据需求,其实可以调整出题策略,不同的情况执行不同的SQL,而不需要在同一条SQL中实现。

解决方案针对以上三个点进行调整。虽然Question表有3万条数据,但是出题的场景其实是针对知识点出题,单个知识点题目最多也只有1000题左右,所以获取未做过的题目时,完全可以使用NOT IN走索引来完成。SQL语句如:

  A:SELECT 题目标识 FROM Question WHERE 知识点={KnowledgePointCode} AND 题目标识 NOT IN (

    SELECT 题目标识 FROM AnswerResult INNER JOIN Question AND Question.知识点={KnowledgePointCode}

    WHERE AnswerResult.用户标识 = {UserId}

  )

针对只做错的题目出题练习就简单了(正确次数 = 0代表只做错),SQL如:

  B:SELECT 题目标识 FROM AnswerResult INNER JOIN Question AND Question.知识点={KnowledgePointCode}

  WHERE AnswerResult.用户标识 = {UserId} AND 正确次数 = 0 ORDER BY 错误次数 DESC

若要对做错、做对或者只做对的题目进行出题,SQL就是这样的(已经对权重进行冗余=IFNULL((0-正确次数)/(正确次数+错误次数),1)):

  C:SELECT 题目标识 FROM AnswerResult INNER JOIN Question AND Question.知识点={KnowledgePointCode}

  WHERE AnswerResult.用户标识 = {UserId} AND 正确次数 > 0 ORDER BY 权重 DESC

 

不足:SQL语句A的查询速度依然是较慢的,虽然有缩小NOT IN的结果集,但这里还是有优化点。园子里的朋友们能不能给点建议?

有人说JOIN是SQL的性能杀手,我觉得主要还是怎么去使用JOIN,MySQL的索引优化相当重要,如果JOIN成为性能瓶颈,可以EXPLAIN看看是不是索引没有建好,并且尽量让迪卡尔乘积尽量小。使用冗余数据避免JOIN,当可能变化的冗余数据被分表之后,更新这些冗余数据就是一件非常头痛的事了。海量数据高并发,确实是一件挺头痛的事。

望园子里有这方面经验的朋友不吝赐教。谢谢。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • MySQL性能优化
  • MySQL性能优化的一些技巧帮助你的数据库
  • MySQL性能优化 出题业务SQL优化
  • MySQL 性能优化的最佳20多条经验分享
  • mysql 性能的检查和调优方法
  • MySQL大数据查询性能优化教程(图)
  • mysql性能优化指南
  • MySQL配置文件my.cnf中文详解附mysql性能优化方法分享
  • MySQL延迟关联性能优化方法
  • MySQL实现批量插入以优化性能的教程

相关文章

  • 2017-05-11MySQL Where 条件语句介绍和运算符小结
  • 2018-12-05详解mysql基于正则实现模糊替换字符串的方法
  • 2018-12-05什么叫MySQL元数据?元数据的介绍及实例代码
  • 2018-12-05MySQL--pt-osc的介绍与使用
  • 2017-05-11MySQL内存表的特性与使用介绍
  • 2018-12-05一列保存多个ID(将多个用逗号隔开的ID转换成用逗号隔开的名称)
  • 2018-12-05有关值处理的文章推荐10篇
  • 2018-12-05SQL SERVER 根据地图经纬度计算距离函数
  • 2018-12-05SqlServer 执行计划及Sql查询优化初探
  • 2018-12-05windows下安装、卸载mysql服务的方法(mysql 5.6 zip解压版安装教程)_MySQL

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • 解析SQL中的Null
    • 安装MySQL 5后无法启动(不能Start service)解决方法小结
    • 关于数据库中架构的相关介绍
    • MySQL中count(), group by, order by的具体使用详解
    • MySQL服务器默认安装之后调节性能的方法
    • 分享一条insert语句批量插入多条记录教程
    • php 生成RSS文件类实例代码
    • mysql中char与varchar的区别分析
    • 一条语句简单解决“每个Y的最新X”的经典sql语句
    • mysql 编码设置命令

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有