• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見(jiàn)諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            MySQL分表優(yōu)化試驗(yàn)

            我們的項(xiàng)目中有好多不等于的情況。今天寫這篇文章簡(jiǎn)單的分析一下怎么個(gè)優(yōu)化法。
            這里的分表邏輯是根據(jù)t_group表的user_name組的個(gè)數(shù)來(lái)分的。
            因?yàn)檫@種情況單獨(dú)user_name字段上的索引就屬于爛索引。起不了啥名明顯的效果。


            1
            、試驗(yàn)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
            、試驗(yàn)表。
            我們用一個(gè)有一千萬(wàn)條記錄的表來(lái)做測(cè)試。

            mysql> select count(*) from t_group;
            +----------+
            | count(*) |
            +----------+
            | 10388608 |
            +----------+
            1 row in set (0.00 sec)

            表結(jié)構(gòu)。
            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
            這個(gè)索引是必須的,因?yàn)橐獙?duì)user_name來(lái)GROUP BY。此時(shí)屬于松散索引掃描!當(dāng)然完了后你可以干掉她。
            idx_user_name
            這個(gè)索引是為了加快單獨(dú)執(zhí)行constant這種類型的查詢。
            我們要根據(jù)用戶名來(lái)分表。

            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)

            所以結(jié)果表應(yīng)該是這樣的。
            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
            、對(duì)比結(jié)果。


            mysql> select count(*) from t_group where user_name = 'david';
            +----------+
            | count(*) |
            +----------+
            | 1298576 |
            +----------+
            1 row in set (1.71 sec)

            執(zhí)行了將近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)
            執(zhí)行了將近10秒,可以想象,這個(gè)是實(shí)際的項(xiàng)目中是不能忍受的。
            mysql> select (select count(*) from t_group) - (select count(*) from t_group_david) as total;
            +---------+
            | total   |
            +---------+
            | 9090032 |
            +---------+
            1 row in set (0.00 sec)
            幾乎是瞬間的。


            我們來(lái)看看聚集函數(shù)。
            對(duì)于原表的操作。


            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)
            其他聚集函數(shù)的結(jié)果就不是FULL INDEX SCAN了。耗時(shí)2.15秒。

            對(duì)于小表的操作。
            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,耗時(shí)1.50秒,不劃算。以此看來(lái)。
            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)

            取得這兩個(gè)結(jié)果也是花了快2秒,快了一點(diǎn)。

            我們來(lái)看看這個(gè)小表的結(jié)構(gòu)。
            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

            現(xiàn)在來(lái)重新對(duì)小表運(yùn)行查詢

            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)

            此時(shí)是瞬間的。
            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)

            這次算是控制在一秒以內(nèi)了。

            mysql> Aborted

            小總結(jié)一下:分出的小表的屬性盡量越少越好。大膽的去干吧。

             

            posted on 2009-06-09 13:34 肥仔 閱讀(281) 評(píng)論(0)  編輯 收藏 引用 所屬分類: 數(shù)據(jù)庫(kù)

            99久久精品无码一区二区毛片 | 亚洲AV无码一区东京热久久| 国产精品久久久久久久久久影院| 久久国产一片免费观看| 国内精品久久久久久久涩爱| 日韩欧美亚洲综合久久| 国产一区二区精品久久| 亚洲а∨天堂久久精品| 国产一区二区精品久久| 久久精品国产色蜜蜜麻豆| 久久777国产线看观看精品| 久久精品国产WWW456C0M| 久久久久99精品成人片试看| 久久精品国产亚洲精品| AV色综合久久天堂AV色综合在 | 亚洲天堂久久精品| 97精品依人久久久大香线蕉97 | 久久久精品免费国产四虎| 亚洲国产天堂久久综合| 亚洲综合婷婷久久| 久久九九有精品国产23百花影院| 亚洲精品国产美女久久久| 美女久久久久久| 久久精品无码免费不卡| 久久伊人精品青青草原高清| 99久久国产综合精品女同图片| 久久WWW免费人成—看片| 热久久国产精品| 久久99国产精品久久久| 久久夜色精品国产噜噜亚洲AV | 久久久久久久久无码精品亚洲日韩| 亚洲伊人久久综合中文成人网| 久久精品这里只有精99品| 九九久久99综合一区二区| 久久影院综合精品| 成人久久综合网| 久久精品国产99国产电影网| 99精品久久精品| 欧美日韩中文字幕久久伊人| 韩国三级大全久久网站| 久久久青草青青亚洲国产免观 |