mysql order by uptime desc 之后 CPU 100%

用户昵称不能为空 2017-07-07 10:36:28

1、order by
mysql 数据库单表数据量达到了70万(主键ID 1 ~ 200万)之后,使用 uptime 排序就会CPU爆表,有时候 200% 。字段 uptime int(11) not null,用来存放数据更新的时间戳,已经加了单独索引,已经 按照主键 hash 分区 10个表,innodb。



2、统计表数据记录总数
当表的数据量达到了100万以上,然后使用 select count(主键) 来统计 行数,执行特别慢 select count(id) from tbname。有无替代方法
...全文
296 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 3 楼 default7 的回复:
[quote=引用 2 楼 yupeigu 的回复:] 1、order by mysql 数据库单表数据量达到了70万(主键ID 1 ~ 200万)之后,使用 uptime 排序就会CPU爆表,有时候 200% 。字段 uptime int(11) not null,用来存放数据更新的时间戳,已经加了单独索引,已经 按照主键 hash 分区 10个表,innodb。 排序是很消耗cpu的,而建索引可以减少排序,但是你建了索引,mysql不一定会去用,这才是问题。 你用这个命令,看一下执行计划,看有没有用索引: explain 你的sql 另外,表分区技术,一般情况下并不能有效的加快查询速度,除非你把你的10个分区,放到不同的物理硬盘上,通过硬件来提高速度。 你建的10个hash分区,举个简单的例子,你要uptime查前1000条数据,而这1000条数据,如果平均分布在10个分区中,也就是每个分区100条,那么要查到这么多的数据,就要从10个分区去取数据,这样反而会更慢。 2、统计表数据记录总数 当表的数据量达到了100万以上,然后使用 select count(主键) 来统计 行数,执行特别慢 select count(id) from tbname。有无替代方法 你用的是innodba所以没办法直接从元数据中取,正常情况下是非常快的count(主键),但是因为你做了hash分区,所以可能反而更慢
SQL order by uptime 排序 的explain 结果如下:

MariaDB [db2_dalu]> explain SELECT `tid`,`uid`, `d2`.`name` AS `d2name`, `c2`.`name` AS `c2name`, `uname`, `title`, `d2`, `c2`, `addtime`, `uptime`,  LEFT(content,220) abstract 
FROM `pre_info` 
LEFT JOIN (SELECT `id`, `name` FROM `pre_area` WHERE `level`=2) `d2` ON  d2.id=d2  
LEFT JOIN (SELECT `id`, `name` FROM `pre_info_cat` WHERE `level`=2) `c2` ON  c2.id=c2  
WHERE (`c2`='13028') AND (`d2`='73') AND (`status` IN (0, 1, 2, -2)) 
ORDER BY `uptime` DESC LIMIT 10 OFFSET 50;

+------+-------------+--------------+--------+-----------------------------------------------------------------------------+-----------------------+---------+----------------------+------+-----------------------------+
| id   | select_type | table        | type   | possible_keys                                                               | key                   | key_len | ref                  | rows | Extra                       |
+------+-------------+--------------+--------+-----------------------------------------------------------------------------+-----------------------+---------+----------------------+------+-----------------------------+
|    1 | SIMPLE      | pre_info     | range  | idx-info-status,idx-info-c2-status,idx-info-d2-status,idx-info-c2-d2-status | idx-info-c2-d2-status | 10      | NULL                 | 1557 | Using where; Using filesort |
|    1 | SIMPLE      | pre_area     | eq_ref | PRIMARY,idx-area-level                                                      | PRIMARY               | 4       | db2_lulu.pre_info.d2 |    1 | Using where                 |
|    1 | SIMPLE      | pre_info_cat | eq_ref | PRIMARY,idx-info-cat-level                                                  | PRIMARY               | 4       | db2_lulu.pre_info.c2 |    1 | Using where                 |
+------+-------------+--------------+--------+-----------------------------------------------------------------------------+-----------------------+---------+----------------------+------+-----------------------------+
3 rows in set (0.00 sec)

如果说表分区会导致更慢,那这样表分区有何用途呢 [/quote] 不是没用,而是的用到地方。 就像用高射炮打蚊子,显然不是高射炮没用,而是没用对地方。。。
zjcxc 2017-07-10
  • 打赏
  • 举报
回复
你这个查询,把索引调整为 c2,d2,status,uptime desc 应该就快了
zjcxc 2017-07-10
  • 打赏
  • 举报
回复
主键 hash 分区 ---------------------- 从查询来看,条件跟主键没关系,也就是查询还是得从 10个分区中拿数据,order by 也跟主键没关系,所以充分说明你的分区没有意义 分区的意义是要让操作控制在尽量省的分区,也就是要访问那些分区,应该能够从查询中直接识别出来
  • 打赏
  • 举报
回复
引用 2 楼 yupeigu 的回复:
1、order by mysql 数据库单表数据量达到了70万(主键ID 1 ~ 200万)之后,使用 uptime 排序就会CPU爆表,有时候 200% 。字段 uptime int(11) not null,用来存放数据更新的时间戳,已经加了单独索引,已经 按照主键 hash 分区 10个表,innodb。 排序是很消耗cpu的,而建索引可以减少排序,但是你建了索引,mysql不一定会去用,这才是问题。 你用这个命令,看一下执行计划,看有没有用索引: explain 你的sql 另外,表分区技术,一般情况下并不能有效的加快查询速度,除非你把你的10个分区,放到不同的物理硬盘上,通过硬件来提高速度。 你建的10个hash分区,举个简单的例子,你要uptime查前1000条数据,而这1000条数据,如果平均分布在10个分区中,也就是每个分区100条,那么要查到这么多的数据,就要从10个分区去取数据,这样反而会更慢。 2、统计表数据记录总数 当表的数据量达到了100万以上,然后使用 select count(主键) 来统计 行数,执行特别慢 select count(id) from tbname。有无替代方法 你用的是innodba所以没办法直接从元数据中取,正常情况下是非常快的count(主键),但是因为你做了hash分区,所以可能反而更慢
SQL order by uptime 排序 的explain 结果如下:

MariaDB [db2_dalu]> explain SELECT `tid`,`uid`, `d2`.`name` AS `d2name`, `c2`.`name` AS `c2name`, `uname`, `title`, `d2`, `c2`, `addtime`, `uptime`,  LEFT(content,220) abstract 
FROM `pre_info` 
LEFT JOIN (SELECT `id`, `name` FROM `pre_area` WHERE `level`=2) `d2` ON  d2.id=d2  
LEFT JOIN (SELECT `id`, `name` FROM `pre_info_cat` WHERE `level`=2) `c2` ON  c2.id=c2  
WHERE (`c2`='13028') AND (`d2`='73') AND (`status` IN (0, 1, 2, -2)) 
ORDER BY `uptime` DESC LIMIT 10 OFFSET 50;

+------+-------------+--------------+--------+-----------------------------------------------------------------------------+-----------------------+---------+----------------------+------+-----------------------------+
| id   | select_type | table        | type   | possible_keys                                                               | key                   | key_len | ref                  | rows | Extra                       |
+------+-------------+--------------+--------+-----------------------------------------------------------------------------+-----------------------+---------+----------------------+------+-----------------------------+
|    1 | SIMPLE      | pre_info     | range  | idx-info-status,idx-info-c2-status,idx-info-d2-status,idx-info-c2-d2-status | idx-info-c2-d2-status | 10      | NULL                 | 1557 | Using where; Using filesort |
|    1 | SIMPLE      | pre_area     | eq_ref | PRIMARY,idx-area-level                                                      | PRIMARY               | 4       | db2_lulu.pre_info.d2 |    1 | Using where                 |
|    1 | SIMPLE      | pre_info_cat | eq_ref | PRIMARY,idx-info-cat-level                                                  | PRIMARY               | 4       | db2_lulu.pre_info.c2 |    1 | Using where                 |
+------+-------------+--------------+--------+-----------------------------------------------------------------------------+-----------------------+---------+----------------------+------+-----------------------------+
3 rows in set (0.00 sec)

如果说表分区会导致更慢,那这样表分区有何用途呢
  • 打赏
  • 举报
回复
1、order by mysql 数据库单表数据量达到了70万(主键ID 1 ~ 200万)之后,使用 uptime 排序就会CPU爆表,有时候 200% 。字段 uptime int(11) not null,用来存放数据更新的时间戳,已经加了单独索引,已经 按照主键 hash 分区 10个表,innodb。 排序是很消耗cpu的,而建索引可以减少排序,但是你建了索引,mysql不一定会去用,这才是问题。 你用这个命令,看一下执行计划,看有没有用索引: explain 你的sql 另外,表分区技术,一般情况下并不能有效的加快查询速度,除非你把你的10个分区,放到不同的物理硬盘上,通过硬件来提高速度。 你建的10个hash分区,举个简单的例子,你要uptime查前1000条数据,而这1000条数据,如果平均分布在10个分区中,也就是每个分区100条,那么要查到这么多的数据,就要从10个分区去取数据,这样反而会更慢。 2、统计表数据记录总数 当表的数据量达到了100万以上,然后使用 select count(主键) 来统计 行数,执行特别慢 select count(id) from tbname。有无替代方法 你用的是innodba所以没办法直接从元数据中取,正常情况下是非常快的count(主键),但是因为你做了hash分区,所以可能反而更慢
rucypli 2017-07-07
  • 打赏
  • 举报
回复
1、order by mysql 数据库单表数据量达到了70万(主键ID 1 ~ 200万)之后,使用 uptime 排序就会CPU爆表,有时候 200% 。字段 uptime int(11) not null,用来存放数据更新的时间戳,已经加了单独索引,已经 按照主键 hash 分区 10个表,innodb。 sql列出来 2、统计表数据记录总数 当表的数据量达到了100万以上,然后使用 select count(主键) 来统计 行数,执行特别慢 select count(id) from tbname。有无替代方法 可以去系统表拿近似的count数据
Re: 《Linux 系统管理命令》 ---------------------------------------内容提要: 01/20)命令lsof          :查看进程打开的文件02/20)命令uptime     :显示系统的运行时间及负载03/20)命令free          :查看系统内存信息04/20)命令iftop         :动态显示网络接口流量信息05/20)命令vmstat      :虚拟内存统计06/20)命令mpstat      :CPU信息统计07/20)命令iostat        :I/O信息统计08/20)命令 iotop        :动态显示磁盘 I/O 统计信息09/20)命令 sar            :收集系统信息10/20)命令 chkconfig :管理开机服务11/20)命令 ntsysv       :管理开机服务12/20)命令 setup        :系统管理工具13/20)命令 ethtool      :查询网卡参数14/20)命令 mii-tool     :管理网络接口的状态15/20)命令 dmidecode:查询系统硬件信息16/20)命令 lspci           :显示所有PCI设备17/20)命令 ipcs            :显示进程间通信设施的状态18/20)命令ipcrm          :清除ipc相关信息19/20)命令rpm             :RPM包管理器20/20)命令yum             :自动化RPM包管理工具  本人在教学和实战过程中发现,即便是有一定运维经验的人,可能已经能够搭建一定复杂度的Linux架构,但是在来来回回的具体操作中,还是体现出CLI(命令界面)功底不够扎实,甚至操作的非常‘拙’、处处露‘怯’。 对一个士兵来说,枪就是他的武器,对于一个程序员来说,各种library(工具库)就是他的武器;而对于Linux运维人员来说,无疑命令行工具CLI(命令界面)就是他们的武器;高手和小白之间的差距往往就体现在对于这些“武器”的掌握和熟练程度上。有时候一个参数就能够解决的事情,小白们可能要写一个复杂的Shell脚本才能搞定,这就是对CLI(命令界面)没有理解参悟透彻导致。 研磨每一个命令就是擦拭手中的作战武器,平时不保养不理解,等到作战的时候,一定不能够将手中的武器发挥到最好,所以我们要平心、静气和专注,甘坐冷板凳一段时间,才能练就一身非凡的内功! 本教程从实战出发,结合当下流行或最新的Linux(v6/7/8 版本)同时演示,将命令行结合到解决企业实战问题中来,体现出教学注重实战的务实精神,希望从事或未来从事运维的同学,能够认真仔细的学完Linux核心命令的整套课程。 本课程系列将逐步推出,看看我教学的进度和您学习的步伐,孰占鳌头! 注:关于教学环境搭建,可以参考本人其它课程系列,本教学中就不再赘述! 《参透 VMware 桌面级虚拟化》 《在虚拟机中安装模版机(包括应用软件等)》 《SecureCRT 连接 GNS3/Linux 的安全精密工具》 

56,677

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧