数据量大表,两种 SQL 实现的优缺点 [ 2.0 版本 ]
提问:record 这个表的数据比较大
/*****************执行sql是分别把6种状态单词count出来********************/
$freeCount = Record::find()->where($where)->andWhere(['status'=>AppointUtil::STATUS_FREE])->count();
//1 - 已预约(未到珍)
$reservedCount = Record::find()->where($where)->andWhere(['status'=>AppointUtil::STATUS_RESERVED])->count();
//2 - 已到诊
$arrivedCount = Record::find()->where($where)->andWhere(['status'=>AppointUtil::STATUS_ARRIVED])->count();
//3 - 不可预约
$cannotCount = Record::find()->where($where)->andWhere(['status'=>AppointUtil::STATUS_CANNOT])->count();
//4 - 失约
$breakCount = Record::find()->where($where)->andWhere(['status'=>AppointUtil::STATUS_BREAK])->count();
//5 - 设备维护,1.4版本后不使用
$disableCount = Record::find()->where($where)->andWhere(['status'=>AppointUtil::STATUS_DISABLE])->count();
/****************执行一条sql按照状态分组 all 全部查询出来*********************/
$data = Record::find()->where($where)->groupBy('status')->asArray()->all();
说明:
- 第一种直接count返回每种状态的值
- 第二种status分组查询所有的,返回二维数组,同时会出现有的状态没有,通过返回的结果需二次处理
问答:请教大佬,以上2种解决方案,那种相对好点,优缺点分别是啥?
备注:考虑 MySQL 性能第一位
共 7 个回答
-
-

说实话,你这两种在数据量大的情况下可能都很慢。
首先:innodb下尽量避免count操作,可以select 主键找到结果,然后通过php的count计数。
其次:尽量使用select,减少mysql每次的io数据量,这往往是数据库的瓶颈。共 2 条回复 -
-
-

不清楚你具体的索引设计 不过第一感觉是 第二种
原因: 不考虑你其他where 条件 就状态条件 1.不命中索引 那么数据多要被从硬盘拉出来 一个状态条件啦一次 groupBy 拉一次数据 就完成统计(如果有哪里不对的 欢迎支出) 2.能命中索引 那么count的时候 就直接出数据了 不需要啦数据了 这个时候 groupBy 和单条的话 groupBy可能优势不是太明显 如果硬要锁缺点的话 就是灵活性了吧 你单个where 可以指定使用索引(更具你具体的业务场景 有些状态牵扯的where中的几个条件是确定的 )具体的业务和表设计不一样 建议通过mysql的explain分析
如果想得到更加详细信息 打开 mysql profiling
set profiling=1 开启分析功能
show profiles 查看执行SQL
select * from INFORMATION_SCHEMA.PROFILING where query_id = id 查看单挑sql的信息 -
-
刘冲💯
注册时间:2017-10-16
最后登录:2021-04-01
在线时长:2小时33分
最后登录:2021-04-01
在线时长:2小时33分
- 粉丝1
- 金钱2470
- 威望0
- 积分2490