设为首页 加入收藏

TOP

table_rows查询优化(一)
2018-04-13 06:06:32 】 浏览:259
Tags:table_rows 查询 优化

日常应用运维工作中,Dev或者db本身都需要统计表的行数,以此作为应用或者维护的一个信息参考。也许很多人会忽略select count(*) from table_name类似的sql对数据库性能的影响,可当你在慢日志平台看到执行了数千次,每次执行4秒左右的查询,你还会无动于衷吗?作为一个有担当敢于挑战的dba,你们应该勇于说no,我觉得类似的需求不可避免但不应该是影响数据库性能的因素,如果连这个都摆不平公司还能指望你干什么。经过几番深思总结,我根据查询的需求,分为模糊查询和精确查询,可以通过下面的三种方式来择优选择。下面测试是线上一个日志表,表大小在6个G左右。


1、精确查询知晓表中数据行数,这个时候我们就要使用count()函数来统计表中行数的大小了。在innodb存储引擎中count(*)函数是先从内存中读取表中的数据到内存缓冲区,然后全表扫描获得记录行数的。但是这种方式过于简单、直接暴力,对于小表查询比较合适,对于频繁的大表查询就不适用了。尤其是在生产中表很大,且表除了聚集索引(主键索引)外,没有其他非聚集索引(二级索引)的时候,无疑是一种巨大的灾难。


mysql> select count(*) from operation_log;
+----------+
| count(*) |
+----------+
| 21049180 |
+----------+
row in set (10.92 sec)


mysql> explain select count(*) from rule_ceshi.operation_log;
+----+-------------+---------------+-------+---------------+----------+---------+------+----------+-------------+
| id | select_type | table        | type  | possible_keys | key      | key_len | ref  | rows    | Extra      |
+----+-------------+---------------+-------+---------------+----------+---------+------+----------+-------------+
|  1 | SIMPLE      | operation_log | index | NULL          | user_key | 194    | NULL | 20660338 | Using index |
+----+-------------+---------------+-------+---------------+----------+---------+------+----------+-------------+
row in set (0.00 sec)


mysql> show index from rule_ceshi.operation_log;
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table        | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| operation_log |          0 | PRIMARY  |            1 | id          | A        |    20660338 |    NULL | NULL  |      | BTREE      |        |              |
| operation_log |          1 | user_key |            1 | user_key    | A        |    2951476 |    NULL | NULL  |      | BTREE      |        |              |
+---------------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
rows in set (0.00 sec)


mysql> drop index user_key on rule_ceshi.operation_log;
Query OK, 0 rows affected (0.19 sec)
Records: 0  Duplicates: 0  Warnings: 0


mysql> select count(*) from rule_ceshi.operation_log;
+----------+
| count(*) |
+----------+
| 21049180 |
+----------+
row in set (23.39 sec)


上面的测试结果表明,count(*)走聚集索引和非聚集索引都是索引全扫描,但是走非聚集索引比走聚集索引获取记录数更快,这是为什么呢?我们通常不是说走主键索引是最快,难道这个原则在这里不适用还是优化器出现bug。当我产生这个疑问的时候,也曾这样怀疑

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇pt-table-checksum工具主从一致性.. 下一篇如何在Ubuntu上安装MySQL/MariaDB

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目