数据量大表,两种 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