mysql查询卡在状态“发送数据”

时间:2016-11-18 06:02:45

标签: mysql query-optimization mysql-cluster

下面的查询占用差不多7个而且我很困惑,如果它在mysqlserver(ndb存储引擎)中的正常行为,在解释输出它也表明它正在使用表索引

    SELECT radgroupreply.groupname, 
    count(distinct(radusergroup.username)) AS users 
    FROM radgroupreply                 
    JOIN radusergroup ON radgroupreply.groupname=radusergroup.groupname                                 
    WHERE
    (radgroupreply.groupname NOT LIKE 'FB-%' 
    AND radgroupreply.groupname <> 'Dropped Corporate Users' 
    AND radgroupreply.groupname <> 'Dropped Broadband Users')
    GROUP BY radgroupreply.groupname 
    UNION 
    SELECT distinct(radgroupcheck.groupname), 
    count(distinct(radusergroup.username))  
    FROM radgroupcheck 
    JOIN radusergroup ON radgroupcheck.groupname=radusergroup.groupname                
    WHERE
    (radgroupcheck.groupname NOT LIKE 'FB-%' 
    AND radgroupcheck.groupname <> 'Dropped Corporate Users' 
    )
    GROUP BY radgroupcheck.groupname ORDER BY groupname asc;

查询的explain输出为: -

  +----+--------------+---------------+-------+---------------+-----------+---------+----------------------------------+------+---------------------------------+
    | id | select_type  | table         | type  | possible_keys | key       | key_len | ref                              | rows | Extra                           |
    +----+--------------+---------------+-------+---------------+-----------+---------+----------------------------------+------+---------------------------------+
    |  1 | PRIMARY      | radgroupreply | range | groupname     | groupname | 66      | NULL                             |   47 | Using where; Using MRR          |
    |  1 | PRIMARY      | radusergroup  | ref   | groupname     | groupname | 66      | ctradius.radgroupreply.groupname |   64 | NULL                            |
    |  2 | UNION        | radgroupcheck | range | groupname     | groupname | 66      | NULL                             |   20 | Using where; Using MRR          |
    |  2 | UNION        | radusergroup  | ref   | groupname     | groupname | 66      | ctradius.radgroupcheck.groupname |  120 | NULL                            |
    |NULL| UNION RESULT | <union1,2>    | ALL   | NULL          | NULL      | NULL    | NULL                             | NULL | Using temporary; Using filesort |
    +----+--------------+---------------+-------+---------------+-----------+---------+----------------------------------+------+---------------------------------+

以下是join

中涉及的表的表结构和索引列信息

表:radgroupreply; #total 192行

    +-----------+------------------+------+-----+---------+----------------+
    | Field     | Type             | Null | Key | Default | Extra          |
    +-----------+------------------+------+-----+---------+----------------+
    | id        | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
    | groupname | varchar(64)      | NO   | MUL |         |                |
    | attribute | varchar(32)      | NO   |     |         |                |
    | op        | char(2)          | NO   |     | =       |                |
    | value     | varchar(253)     | NO   |     |         |                |
    +-----------+------------------+------+-----+---------+----------------+

表:radusergroup #total:~13000行

    +-----------+-------------+------+-----+---------+----------------+
    | Field     | Type        | Null | Key | Default | Extra          |
    +-----------+-------------+------+-----+---------+----------------+
    | id        | int(11)     | NO   | PRI | NULL    | auto_increment |
    | username  | varchar(64) | NO   | MUL |         |                |
    | groupname | varchar(64) | NO   | MUL |         |                |
    | priority  | int(11)     | NO   |     | 1       |                |
    +-----------+-------------+------+-----+---------+----------------+

表:radgroupcheck #totalrows:~100

    +-----------+------------------+------+-----+---------+----------------+
    | Field     | Type             | Null | Key | Default | Extra          |
    +-----------+------------------+------+-----+---------+----------------+
    | id        | int(11) unsigned | NO   | PRI | NULL    | auto_increment |
    | groupname | varchar(64)      | NO   | MUL |         |                |
    | attribute | varchar(32)      | NO   |     |         |                |
    | op        | char(2)          | NO   |     | ==      |                |
    | value     | varchar(253)     | NO   |     |         |                |
    +-----------+------------------+------+-----+---------+----------------+


    #radusergroup# CREATE TABLE `radusergroup` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(64) NOT NULL DEFAULT '',
      `groupname` varchar(64) NOT NULL DEFAULT '',
      `priority` int(11) NOT NULL DEFAULT '1',
      PRIMARY KEY (`id`),
      KEY `groupname` (`groupname`),
      KEY `username` (`username`)
    ) ENGINE=ndbcluster AUTO_INCREMENT=12380 DEFAULT CHARSET=latin1

   #show index from radusergroup
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table         | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | radgroupreply |          0 | PRIMARY   |            1 | id          | A         |         192 |     NULL | NULL   |      | BTREE      |         |               |
    | radgroupreply |          1 | groupname |            1 | groupname   | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

    #radgroupreply# CREATE TABLE `radgroupreply` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `groupname` varchar(64) NOT NULL DEFAULT '',
    `attribute` varchar(32) NOT NULL DEFAULT '',
    `op` char(2) NOT NULL DEFAULT '=',
    `value` varchar(253) NOT NULL DEFAULT '',
    PRIMARY KEY (`id`),
    KEY `groupname` (`groupname`)
    ) ENGINE=ndbcluster AUTO_INCREMENT=2410 DEFAULT CHARSET=latin1
    mysql> show index from radgroupreply;

    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table         | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | radgroupreply |          0 | PRIMARY   |            1 | id          | A         |         192 |     NULL | NULL   |      | BTREE      |         |               |
    | radgroupreply |          1 | groupname |            1 | groupname   | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

   #radgroupcheck#  CREATE TABLE `radgroupcheck` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `groupname` varchar(64) NOT NULL DEFAULT '',
      `attribute` varchar(32) NOT NULL DEFAULT '',
      `op` char(2) NOT NULL DEFAULT '==',
      `value` varchar(253) NOT NULL DEFAULT '',
      PRIMARY KEY (`id`),
      KEY `groupname` (`groupname`)
    ) ENGINE=ndbcluster AUTO_INCREMENT=588 DEFAULT CHARSET=latin1

     mysql> show index from radgroupcheck;
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | Table         | Non_unique | Key_name  | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
    | radgroupcheck |          0 | PRIMARY   |            1 | id          | A         |         103 |     NULL | NULL   |      | BTREE      |         |               |
    | radgroupcheck |          1 | groupname |            1 | groupname   | A         |        NULL |     NULL | NULL   |      | BTREE      |         |               |
    +---------------+------------+-----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+


mysql>  SELECT @@GLOBAL.tx_isolation, @@tx_isolation, @@session.tx_isolation; 
+-----------------------+----------------+------------------------+
| @@GLOBAL.tx_isolation | @@tx_isolation | @@session.tx_isolation |
 +-----------------------+----------------+------------------------+
| READ-COMMITTED        | READ-COMMITTED | READ-COMMITTED         |
+-----------------------+----------------+------------------------+

更新:查询

(SELECT radgroupreply.groupname, 
    count(distinct(radusergroup.username)) AS users 
    FROM radgroupreply                 
    JOIN radusergroup ON radgroupreply.groupname=radusergroup.groupname                                 
    WHERE
    (radgroupreply.groupname NOT LIKE 'FB-%' AND radgroupreply.groupname <> 'Dropped Corporate Users' AND radgroupreply.groupname <> 'Dropped Broadband Users')
    GROUP BY radgroupreply.groupname )
    UNION 
    (SELECT radgroupcheck.groupname, 
    count(distinct(radusergroup.username))  
    FROM radgroupcheck 
    JOIN radusergroup ON radgroupcheck.groupname=radusergroup.groupname                
    WHERE
    (radgroupcheck.groupname NOT LIKE 'FB-%' AND radgroupcheck.groupname <> 'Dropped Corporate Users')
    GROUP BY radgroupcheck.groupname ORDER BY groupname asc);

解释: -

+----+--------------+---------------+-------+---------------+-----------+---------+----------------------------------+------+------------------------+
    | id | select_type  | table         | type  | possible_keys | key       | key_len | ref                              | rows | Extra                  |
    +----+--------------+---------------+-------+---------------+-----------+---------+----------------------------------+------+------------------------+
    |  1 | PRIMARY      | radgroupreply | range | groupname     | groupname | 66      | NULL                             |   47 | Using where; Using MRR |
    |  1 | PRIMARY      | radusergroup  | ref   | groupname     | groupname | 66      | ctradius.radgroupreply.groupname |   64 | NULL                   |
    |  2 | UNION        | radgroupcheck | range | groupname     | groupname | 66      | NULL                             |   20 | Using where; Using MRR |
    |  2 | UNION        | radusergroup  | ref   | groupname     | groupname | 66      | ctradius.radgroupcheck.groupname |  121 | NULL                   |
    |NULL| UNION RESULT | <union1,2>    | ALL   | NULL          | NULL      | NULL    | NULL                             | NULL | Using temporary        |
    +----+--------------+---------------+-------+---------------+-----------+---------+----------------------------------+------+------------------------+

2 个答案:

答案 0 :(得分:2)

由于您已GROUPing BY列已将SELECT distinct(radgroupcheck.groupname)更改为SELECT radgroupcheck.groupname

添加括号以澄清UNION正在排序,而不仅仅是最后SELECT

( SELECT ... ) UNION ( SELECT ... ) ORDER BY ...

根据提示here更改many:many表(引擎除外)。

group_replygroup_check似乎有相同的模式;他们分开的原因是什么?

group_replygroup_check中是否有可用于PRIMARY KEY的唯一列(或列对)?

<强>改造

SELECT  groupname, 
        ( SELECT  count(distinct username)
            FROM  radusergroup  WHERE groupname = u.groupname 
        ) AS users
    FROM  ( 
            (
                SELECT  r.groupname
                    FROM  radgroupreply AS r
                    WHERE  r.groupname NOT LIKE 'FB-%'
                      AND  r.groupname <> 'Dropped Corporate Users'
                      AND  r.groupname <> 'Dropped Broadband Users' 
            )
            UNION  DISTINCT --  or  UNION  ALL ? 
            (
                SELECT  c.groupname
                    FROM  radgroupcheck AS c
                    WHERE  c.groupname NOT LIKE 'FB-%'
                      AND  c.groupname <> 'Dropped Corporate Users'
            ) 
          ) AS u
    ORDER BY  groupname asc 

答案 1 :(得分:1)

我会把这个查询改写成这个:

SELECT radgroupreply.groupname, 
       count(distinct radusergroup.username  ) AS users,
       count(distinct CASE 
                      WHEN radgroupreply.groupname <> 'Dropped Broadband Users'
                      THEN radusergroup.username
             END )  As users_without_dropped_broadband
FROM radgroupreply                 
JOIN radusergroup ON radgroupreply.groupname=radusergroup.groupname                                 
WHERE
     (radgroupreply.groupname NOT LIKE 'FB-%' 
     AND radgroupreply.groupname <> 'Dropped Corporate Users' )
GROUP BY radgroupreply.groupname 
ORDER BY groupname asc
;

上述查询以稍微不同的形式显示结果:

| gropname | users | users_without_dropped_broadband |
| A        |    20 |                              13 |
| B        |    33 |                              11 |

比oryginal查询的布局:

| gropname | users |
| A        |    20 |
| A        |    13 |
| B        |    33 |
| B        |    11 |

但是这个新查询执行所有操作(读取表格,联接,计数等)仅一次,不是原始查询的两倍,并且应该至少快50%( &lt; 3,5秒)。