zoukankan      html  css  js  c++  java
  • mysql 分表与分区

    一.操作环境

       数据达到百w甚于更多的时候,我们的mysql查询将会变得比较慢, 如果再加上连表查询,程序可能会卡死。即使你设置了索引并在查询中使用到了索引,查询还是会慢。这时候你就要考虑怎么样来提高查询速度了。

       抛弃其他的不讲,只从mysql本身的优化来讲,我所知道的方法有三种:mysql集群,mysql分表,mysql分区

    二.mysql集群

       mysql集群成本比较高,不过这不是这里讲的重点,后期开一篇文章,专门来讲这方面的知识。

    三.mysql分表

      1. 当数据达到百w,千w的时候,我们就想着怎么把表数据分流到不同的表中去,缩小单个表的体积,表的操作最后还是归根到对磁盘文件的操作,小文件的IO速度肯定要比大文件的速度要快。

      2.分表的方式:分表有横向分表和纵向分表两种方式。

        横向分表:指把表的数据分流要不同的表中去,比如100W的表数据分流到10个表中,每个表就只有10w条数据。

        纵向分表:指的是拆分表的结构,比如把新闻的标题和新闻的内容拆开,放到不同的表中。这种方法主要是运用在前期的表开始设计阶段。

       3. 着重讲一个横向分表的方法:

           1):hash算法,就是通过一定的算法,得出一个值,再根据这个值知道去操作对应的表,比如我想分10个表,user1,user2,user3..........假设我们用uid来做为分表的计算字段,通过取余的方式来。某个用户的用户ID是5,5%10=5,那这个用户的数据就是放在user5这个表中。    这就是取余算法,当然还有其他的,具体根据实际业务的需求来定。

           2):利用mysql本身的分表引擎merge

                  这种方式适合在设计表的时候考虑不周,已经出现大的数据,并查询缓慢的情况 。这种方式对程序代码的改动比较小,因为sql语句写好了,如果再采用第一种的分表方式的话,一个表拆分成多个表了,那程序代码对表的操作都要改。麻烦啊。

                

    1. mysql> CREATE TABLE IF NOT EXISTS `user1` (  
    2.  ->   `id` int(11) NOT NULL AUTO_INCREMENT,  
    3.  ->   `name` varchar(50) DEFAULT NULL,  
    4.  ->   `sex` int(1) NOT NULL DEFAULT '0',  
    5.  ->   PRIMARY KEY (`id`)  
    6.  -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;  
    7. Query OK, 0 rows affected (0.05 sec)  
    8.   
    9. mysql> CREATE TABLE IF NOT EXISTS `user2` (  
    10.  ->   `id` int(11) NOT NULL AUTO_INCREMENT,  
    11.  ->   `name` varchar(50) DEFAULT NULL,  
    12.  ->   `sex` int(1) NOT NULL DEFAULT '0',  
    13.  ->   PRIMARY KEY (`id`)  
    14.  -> ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;  
    15. Query OK, 0 rows affected (0.01 sec)  
    16.   
    17. mysql> INSERT INTO `user1` (`name`, `sex`) VALUES('张映', 0);  
    18. Query OK, 1 row affected (0.00 sec)  
    19.   
    20. mysql> INSERT INTO `user2` (`name`, `sex`) VALUES('tank', 1);  
    21. Query OK, 1 row affected (0.00 sec)  
    22.   
    23. mysql> CREATE TABLE IF NOT EXISTS `alluser` (  
    24.  ->   `id` int(11) NOT NULL AUTO_INCREMENT,  
    25.  ->   `name` varchar(50) DEFAULT NULL,  
    26.  ->   `sex` int(1) NOT NULL DEFAULT '0',  
    27.  ->   INDEX(id)  
    28.  -> ) TYPE=MERGE UNION=(user1,user2) INSERT_METHOD=LAST AUTO_INCREMENT=1 ;  
    29. Query OK, 0 rows affected, 1 warning (0.00 sec)  
    30.   
    31. mysql> select id,name,sex from alluser;  
    32. +----+--------+-----+  
    33. | id | name   | sex |  
    34. +----+--------+-----+  
    35. |  1 | 张映 |   0 |  
    36. |  1 | tank   |   1 |  
    37. +----+--------+-----+  
    38. 2 rows in set (0.00 sec)  
    39.   
    40. mysql> INSERT INTO `alluser` (`name`, `sex`) VALUES('tank2', 0);  
    41. Query OK, 1 row affected (0.00 sec)  
    42.   
    43. mysql> select id,name,sex from user2  
    44.  -> ;  
    45. +----+-------+-----+  
    46. | id | name  | sex |  
    47. +----+-------+-----+  
    48. |  1 | tank  |   1 |  
    49. |  2 | tank2 |   0 |  
    50. +----+-------+-----+  
    51. 2 rows in set (0.00 sec) 

                 

    a,如果你使用 alter table 来把 merge 表变为其它表类型,到底层表的映射就被丢失了。取而代之的,来自底层 myisam 表的行被复制到已更换的表中,该表随后被指定新类型。

    b,网上看到一些说replace不起作用,我试了一下可以起作用的。晕一个先

    c,一个 merge 表不能在整个表上维持 unique 约束。当你执行一个 insert,数据进入第一个或者最后一个 myisam 表(取决于 insert_method 选项的值)。mysql 确保唯一键值在那个 myisam 表里保持唯一,但不是跨集合里所有的表。

    d,当你创建一个 merge 表之时,没有检查去确保底层表的存在以及有相同的机构。当 merge 表被使用之时,mysql 检查每个被映射的表的记录长度是否相等,但这并不十分可靠。如果你从不相似的 myisam 表创建一个 merge 表,你非常有可能撞见奇怪的问题。

      

          3):第一种与第二种的比较,第一种的效率会比较高,但是第二种的扩展性会好一点。

    四:表分区

    当数据量非常大时(表的容量到达GB或者是TB),如果仍然采用索引的方式来优化查询,由于索引本生的消耗以及大量的索引碎片的产生,查询的过程会导致大量的随机I/O的产生,在这种场景下除非可以很好的利用覆盖索引,否则由于在查询的过程中需要根据索引回数据表查询,会导致性能受到很大的影响,这时可以考虑通过分区表的策略来提高查询的性能

  • 相关阅读:
    关于CTeX的几个大坑
    latex与word之间的各种转化方法
    事件的三种绑定方式
    实例操作JSONP原理
    Content Security Policy 入门教程
    video.js
    Javascript面向对象类文章目录
    javaScript的原型继承与多态性
    javaScript的变量
    document.documentElement.clientHeight 与 document.body.clientHeight(杜绝千篇一律的抄袭!!)
  • 原文地址:https://www.cnblogs.com/myblog1314/p/4539589.html
Copyright © 2011-2022 走看看