首页 数据库 mysql教程 MySQL分表优化_MySQL

MySQL分表优化_MySQL

Jun 01, 2016 pm 01:43 PM
优化 文章

bitsCN.com 我们的项目中有好多不等于的情况。今天写这篇文章简单的分析一下怎么个优化法。
 
  这里的分表逻辑是根据t_group表的user_name组的个数来分的。
  因为这种情况单独user_name字段上的索引就属于烂索引。起不了啥名明显的效果。
  1、试验PROCEDURE.
 
DELIMITER $$
Drop PROCEDURE `t_girl`.`sp_split_table`$$
Create PROCEDURE `t_girl`.`sp_split_table`()
BEGIN
 declare done int default 0;
 declare v_user_name varchar(20) default '';
 declare v_table_name varchar(64) default '';
 -- Get all users' name.
 declare cur1 cursor for select user_name from t_group group by user_name;
 -- Deal with error or warnings.
 declare continue handler for 1329 set done = 1;
 -- Open cursor.
 open cur1;
 while done 1
 do
  fetch cur1 into v_user_name;
  if not done then
   -- Get table name.
   set v_table_name = concat('t_group_',v_user_name);
   -- Create new extra table.
   set @stmt = concat('create table ',v_table_name,' like t_group');
   prepare s1 from @stmt;
   execute s1;
   drop prepare s1;
   -- Load data into it.
   set @stmt = concat('insert into ',v_table_name,' select * from t_group where user_name = ''',v_user_name,'''');
   prepare s1 from @stmt;
   execute s1;
   drop prepare s1;
  end if;
 end while;
 -- Close cursor.
 close cur1;
 -- Free variable from memory.
 set @stmt = NULL;
END$$
DELIMITER ;
 
  2、试验表。
  我们用一个有一千万条记录的表来做测试。
 
mysql> select count(*) from t_group;
+----------+
| count(*) |
+----------+
| 10388608 |
+----------+
1 row in set (0.00 sec)
 
  表结构。
 
mysql> desc t_group;
+-------------+------------------+------+-----+-------------------+----------------+
| Field   | Type      | Null | Key | Default     | Extra     |
+-------------+------------------+------+-----+-------------------+----------------+
| id     | int(10) unsigned | NO | PRI | NULL       | auto_increment |
| money   | decimal(10,2)  | NO |  |         |        |
| user_name | varchar(20)   | NO | MUL |         |        |
| create_time | timestamp    | NO |  | CURRENT_TIMESTAMP |        |
+-------------+------------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)
 
  索引情况。
 
mysql> show index from t_group;
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
|Table | Non_unique | Key_name    | Seq_in_index | Column_name |Collation | Cardinality | Sub_part | Packed | Null | Index_type |Comment |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
|t_group |     0 | PRIMARY     |      1 | id     |A    |  10388608 |  NULL | NULL |   | BTREE  |    |
| t_group |     1 | idx_user_name  |     1 | user_name | A    |     8 |  NULL | NULL |   |BTREE   |    |
| t_group |     1 | idx_combination1|      1 | user_name | A    |     8 |  NULL |NULL |   | BTREE   |    |
| t_group |     1 |idx_combination1 |      2 | money   | A    |    3776|  NULL | NULL |   | BTREE   |    |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
4 rows in set (0.00 sec)
 
  PS:
  idx_combination1 这个索引是必须的,因为要对user_name来GROUP BY。此时属于松散索引扫描!当然完了后你可以干掉她。
  idx_user_name 这个索引是为了加快单独执行constant这种类型的查询。
  我们要根据用户名来分表
 mysql> select user_name from t_group where 1 group by user_name;
+-----------+
| user_name |
+-----------+
| david  |
| leo   |
| livia  |
| lucy   |
| sarah  |
| simon  |
| sony   |
| sunny  |
+-----------+
8 rows in set (0.00 sec)
 
  所以结果表应该是这样的。
 
mysql> show tables like 't_group_%';
+------------------------------+
| Tables_in_t_girl (t_group_%) |
+------------------------------+
| t_group_david        |
| t_group_leo         |
| t_group_livia        |
| t_group_lucy        |
| t_group_sarah        |
| t_group_simon        |
| t_group_sony        |
| t_group_sunny        |
+------------------------------+
8 rows in set (0.00 sec)
 
  3、对比结果。
 
mysql> select count(*) from t_group where user_name = 'david';
+----------+
| count(*) |
+----------+
| 1298576 |
+----------+
1 row in set (1.71 sec)
 
  执行了将近2秒。
 
mysql> select count(*) from t_group_david;
+----------+
| count(*) |
+----------+
| 1298576 |
+----------+
1 row in set (0.00 sec)
 
  几乎是瞬间的。
 
mysql> select count(*) from t_group where user_name 'david';
+----------+
| count(*) |
+----------+
| 9090032 |
+----------+
1 row in set (9.26 sec)
执行了将近10秒,可以想象,这个是实际的项目中是不能忍受的。
mysql> select (select count(*) from t_group) - (select count(*) from t_group_david) as total;
+---------+
| total |
+---------+
| 9090032 |
+---------+
1 row in set (0.00 sec)
 
  几乎是瞬间的。
  我们来看看聚集函数。
  对于原表的操作。
 
mysql> select min(money),max(money) from t_group where user_name = 'david';
+------------+------------+
| min(money) | max(money) |
+------------+------------+
|   -6.41 |  500.59 |
+------------+------------+
1 row in set (0.00 sec)
最小,最大值都是FULL INDEX SCAN。所以是瞬间的。
mysql> select sum(money),avg(money) from t_group where user_name = 'david';
+--------------+------------+
| sum(money) | avg(money) |
+--------------+------------+
| 319992383.84 | 246.417910 |
+--------------+------------+
1 row in set (2.15 sec)
其他聚集函数的结果就不是FULL INDEX SCAN了。耗时2.15秒。
 
  对于小表的操作。
 
mysql> select min(money),max(money) from t_group_david;
+------------+------------+
| min(money) | max(money) |
+------------+------------+
|   -6.41 |  500.59 |
+------------+------------+
1 row in set (1.50 sec)
 
  最大最小值完全是FULL TABLE SCAN,耗时1.50秒,不划算。以此看来。
 
mysql> select sum(money),avg(money) from t_group_david;
+--------------+------------+
| sum(money) | avg(money) |
+--------------+------------+
| 319992383.84 | 246.417910 |
+--------------+------------+
1 row in set (1.68 sec)
 
  取得这两个结果也是花了快2秒,快了一点。
  我们来看看这个小表的结构。
 
mysql> desc t_group_david;
+-------------+------------------+------+-----+-------------------+----------------+
| Field   | Type      | Null | Key | Default     | Extra     |
+-------------+------------------+------+-----+-------------------+----------------+
| id     | int(10) unsigned | NO | PRI | NULL       | auto_increment |
| money   | decimal(10,2)  | NO |  |         |        |
| user_name | varchar(20)   | NO | MUL |         |        |
| create_time | timestamp    | NO |  | CURRENT_TIMESTAMP |        |
+-------------+------------------+------+-----+-------------------+----------------+
4 rows in set (0.00 sec)
 
  明显的user_name属性是多余的。那么就干掉它。
 
mysql> alter table t_group_david drop user_name;
Query OK, 1298576 rows affected (7.58 sec)
Records: 1298576 Duplicates: 0 Warnings: 0
 
  现在来重新对小表运行查询
 
mysql> select min(money),max(money) from t_group_david;
+------------+------------+
| min(money) | max(money) |
+------------+------------+
|   -6.41 |  500.59 |
+------------+------------+
1 row in set (0.00 sec)
 
  此时是瞬间的。
 
mysql> select sum(money),avg(money) from t_group_david;
+--------------+------------+
| sum(money) | avg(money) |
+--------------+------------+
| 319992383.84 | 246.417910 |
+--------------+------------+
1 row in set (0.94 sec)
 
  这次算是控制在一秒以内了。
  mysql> Aborted
  小总结一下:分出的小表的属性尽量越少越好。大胆的去干吧
 
 
 
第零空间版权所有
  bitsCN.com

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
2 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

今日头条发布文章怎么才能有收益?今日头条发布文章获得更多收益方法! 今日头条发布文章怎么才能有收益?今日头条发布文章获得更多收益方法! Mar 15, 2024 pm 04:13 PM

一、今日头条发布文章怎么才能有收益?今日头条发布文章获得更多收益方法!1.开通基础权益:原创文章选择投放广告可获得收益,视频必须要原创横屏才会有收益。2.开通百粉权益:粉丝量达到百粉以上,微头条、原创问答创作及问答均可获得收益。3.坚持原创作品:原创作品包含文章、微头条及问题等,要求300字以上。注意违规抄袭作品作为原创发布,会被扣信用分,即使有收益也会被扣除。4.垂直度:做专业领域一类的文章,不能随意跨领域写文章,会得不到合适的推荐,达不到作品的专和精,难以吸引粉丝读者。5.活跃度:活跃度高,

Win11新电脑收到后怎么优化设置提升性能? Win11新电脑收到后怎么优化设置提升性能? Mar 03, 2024 pm 09:01 PM

我们在收到新电脑后要怎么设置优化性能,用户们可以直接的打开隐私和安全性,然后点击常规(广告ID,本地内容,应用启动,设置建议,生产力工具或者是直接的打开本地组策略编辑器来进行操作就可以了。下面就让本来为用户们来仔细的介绍一下Win11新电脑收到后如何优化设置提升性能的方法吧。Win11新电脑收到后如何优化设置提升性能的方法方法一:1、按【Win+i】组合键,打开设置,然后左侧点击【隐私和安全性】,右侧点击Windows权限下的【常规(广告ID,本地内容,应用启动,设置建议,生产力工具)】。方法二

Golang的gc优化策略探讨 Golang的gc优化策略探讨 Mar 06, 2024 pm 02:39 PM

Golang的垃圾回收(GC)一直是开发者们关注的一个热门话题。Golang作为一门快速的编程语言,其自带的垃圾回收器能够很好地管理内存,但随着程序规模的增大,有时候会出现一些性能问题。本文将探讨Golang的GC优化策略,并提供一些具体的代码示例。Golang中的垃圾回收Golang的垃圾回收器采用的是基于并发标记-清除(concurrentmark-s

深度解读:为何Laravel速度慢如蜗牛? 深度解读:为何Laravel速度慢如蜗牛? Mar 07, 2024 am 09:54 AM

Laravel是一款广受欢迎的PHP开发框架,但有时候被人诟病的就是其速度慢如蜗牛。究竟是什么原因导致了Laravel的速度不尽如人意呢?本文将从多个方面深度解读Laravel速度慢如蜗牛的原因,并结合具体的代码示例,帮助读者更深入地了解此问题。1.ORM查询性能问题在Laravel中,ORM(对象关系映射)是一个非常强大的功能,可以让

解码Laravel性能瓶颈:优化技巧全面揭秘! 解码Laravel性能瓶颈:优化技巧全面揭秘! Mar 06, 2024 pm 02:33 PM

解码Laravel性能瓶颈:优化技巧全面揭秘!Laravel作为一款流行的PHP框架,为开发者提供了丰富的功能和便捷的开发体验。然而,随着项目规模增大和访问量增加,我们可能会面临性能瓶颈的挑战。本文将深入探讨Laravel性能优化的技巧,帮助开发者发现并解决潜在的性能问题。一、数据库查询优化使用Eloquent延迟加载在使用Eloquent查询数据库时,避免

C++ 程序优化:时间复杂度降低技巧 C++ 程序优化:时间复杂度降低技巧 Jun 01, 2024 am 11:19 AM

时间复杂度衡量算法执行时间与输入规模的关系。降低C++程序时间复杂度的技巧包括:选择合适的容器(如vector、list)以优化数据存储和管理。利用高效算法(如快速排序)以减少计算时间。消除多重运算以减少重复计算。利用条件分支以避免不必要的计算。通过使用更快的算法(如二分搜索)来优化线性搜索。

Laravel性能瓶颈揭秘:优化方案大揭秘! Laravel性能瓶颈揭秘:优化方案大揭秘! Mar 07, 2024 pm 01:30 PM

Laravel性能瓶颈揭秘:优化方案大揭秘!随着互联网技术的发展,网站和应用程序的性能优化变得愈发重要。作为一款流行的PHP框架,Laravel在开发过程中可能会面临性能瓶颈。本文将探讨Laravel应用程序可能遇到的性能问题,并提供一些优化方案和具体的代码示例,让开发者能够更好地解决这些问题。一、数据库查询优化数据库查询是Web应用中常见的性能瓶颈之一。在

Vivox100s参数配置大揭秘:处理器性能如何优化? Vivox100s参数配置大揭秘:处理器性能如何优化? Mar 24, 2024 am 10:27 AM

Vivox100s参数配置大揭秘:处理器性能如何优化?在当今科技飞速发展的时代,智能手机已经成为我们日常生活不可或缺的一部分。作为智能手机的一个重要组成部分,处理器的性能优化直接关系到手机的使用体验。Vivox100s作为一款备受瞩目的智能手机,其参数配置备受关注,尤其是处理器性能的优化问题更是备受用户关注。处理器作为手机的“大脑”,直接影响到手机的运行速度

See all articles