相同的mysql查询在mysql中花费比mariadb更长的时间

时间:2018-07-17 07:13:29

标签: mysql mariadb

我从MariaDB迁移到Mysql。我下面的查询在Mysql中花费超过三分钟,而在MariaDB中花费不到一分钟。 Mysql版本是5.7。 请提出我该如何解决这个问题,非常感谢!!!

SELECT 
COUNT(*)
FROM
(SELECT i.*, f.*, c.*, ft.*, -- summarized for readability
        (SELECT f1.id
         FROM sys_exten_flow_task f1
         WHERE f1.instance_id = f.INSTANCE_ID AND state = '1'
         ORDER BY f1.update_date DESC
         LIMIT 0 , 1) AS pretaskid,
        CASE
            WHEN i.FLOW_DEFINE IS NULL THEN 'free'
            ELSE i.FLOW_DEFINE
        END AS fd,
        CASE
            WHEN f.TASK_DEFINE_ID IS NULL THEN 'free'
            ELSE f.TASK_DEFINE_ID
        END AS tdi
FROM
    sys_exten_flow_task f, sys_exten_flow_instance i,
    sys_exten_flow_define_task dt, sys_user c, sys_dict ft
WHERE
    i.ID = f.INSTANCE_ID
        AND i.CREATE_BY = c.ID
        AND i.FLOW_TYPE = ft.ID
        AND dt.id = f.task_define_id) a;

+----------+
| count(*) |
+----------+
|  3841309 |
+----------+
1 row in set (3 min 21.97 sec)

说明计划

+----+--------------------+------------+------------+--------+--------------------------------------------------+------------------------+---------+----------------------------+---------+----------+---------------------------------------+
| id | select_type        | table      | partitions | type   | possible_keys                                    | key                    | key_len | ref                        | rows    | filtered | Extra                                 |
+----+--------------------+------------+------------+--------+--------------------------------------------------+------------------------+---------+----------------------------+---------+----------+---------------------------------------+
|  1 | PRIMARY            | <derived2> | NULL       | ALL    | NULL                                             | NULL                   | NULL    | NULL                       | 3640604 |   100.00 | NULL                                  |
|  2 | DERIVED            | i          | NULL       | ALL    | PRIMARY,CREATE_BY                                | NULL                   | NULL    | NULL                       |  788059 |   100.00 | Using where                           |
|  2 | DERIVED            | ft         | NULL       | eq_ref | PRIMARY,ID                                       | PRIMARY                | 258     | scdxoa.i.FLOW_TYPE         |       1 |   100.00 | Using where                           |
|  2 | DERIVED            | c          | NULL       | eq_ref | PRIMARY,ID                                       | PRIMARY                | 258     | scdxoa.i.CREATE_BY         |       1 |   100.00 | NULL                                  |
|  2 | DERIVED            | f          | NULL       | ref    | INDEX_TASK_INSTANCE_ID,INDEX_TASK_TASK_DEFINE_ID | INDEX_TASK_INSTANCE_ID | 402     | scdxoa.i.ID                |       4 |   100.00 | Using index condition; Using where    |
|  2 | DERIVED            | dt         | NULL       | eq_ref | PRIMARY                                          | PRIMARY                | 258     | scdxoa.f.TASK_DEFINE_ID    |       1 |   100.00 | Using where                           |
|  3 | DEPENDENT SUBQUERY | f1         | NULL       | ref    | INDEX_TASK_STATUS,INDEX_TASK_INSTANCE_ID,INDEX   | INDEX                  | 408     | const,scdxoa.f.INSTANCE_ID |       3 |   100.00 | Using index condition; Using filesort |
+----+--------------------+------------+------------+--------+--------------------------------------------------+------------------------+---------+----------------------------+---------+----------+---------------------------------------+

7 rows in set, 2 warnings (0.01 sec)

我在MariaDB中执行相同的查询,

+----------+
| count(*) |
+----------+
|  3912445 |
+----------+
1 row in set (56.54 sec)

说明计划

+------+--------------------+-------+--------+--------------------------------------------------+------------------------+---------+-------------------------+-------+----------+------------------------------------+

| id   | select_type        | table | type   | possible_keys                                    | key                    | key_len | ref                     | rows  | filtered | Extra                              |
+------+--------------------+-------+--------+--------------------------------------------------+------------------------+---------+-------------------------+-------+----------+------------------------------------+
|    1 | PRIMARY            | c     | index  | PRIMARY,ID                                       | group_login_name       | 205     | NULL                    | 23047 |   100.00 | Using index                        |
|    1 | PRIMARY            | i     | ref    | PRIMARY,CREATE_BY                                | CREATE_BY              | 259     | scdxoa.c.ID             |    15 |   100.00 |                                    |
|    1 | PRIMARY            | ft    | eq_ref | PRIMARY,ID                                       | PRIMARY                | 258     | scdxoa.i.FLOW_TYPE      |     1 |   100.00 | Using where; Using index           |
|    1 | PRIMARY            | f     | ref    | INDEX_TASK_INSTANCE_ID,INDEX_TASK_TASK_DEFINE_ID | INDEX_TASK_INSTANCE_ID | 402     | scdxoa.i.ID             |     2 |   100.00 | Using index condition; Using where |
|    1 | PRIMARY            | dt    | eq_ref | PRIMARY                                          | PRIMARY                | 258     | scdxoa.f.TASK_DEFINE_ID |     1 |   100.00 | Using where; Using index           |
|    3 | DEPENDENT SUBQUERY | f1    | ref    | INDEX_TASK_STATUS,INDEX_TASK_INSTANCE_ID,INDEX   | INDEX_TASK_INSTANCE_ID | 402     | scdxoa.f.INSTANCE_ID    |     2 |   100.00 | Using where; Using filesort        |
+------+--------------------+-------+--------+--------------------------------------------------+------------------------+---------+-------------------------+-------+----------+------------------------------------+

6 rows in set, 2 warnings (0.00 sec)

我还尝试让Mysql对mariadb的结果sql进行优化。

select count(0) AS "count(*)" 
from "scdxoa"."sys_exten_flow_task" "f" 
join "scdxoa"."sys_exten_flow_instance" "i" 
join "scdxoa"."sys_exten_flow_define_task" "dt" 
join "scdxoa"."sys_user" "c" 
join "scdxoa"."sys_dict" "ft" 
where (("scdxoa"."i"."CREATE_BY" = "scdxoa"."c"."ID") 
     and ("scdxoa"."i"."ID" = "scdxoa"."f"."INSTANCE_ID") 
     and ("scdxoa"."i"."FLOW_TYPE" = "scdxoa"."ft"."ID") 
     and ("scdxoa"."dt"."ID" = "scdxoa"."f"."TASK_DEFINE_ID"));
+----------+
| count(*) |
+----------+
|  3841309 |
+----------+
1 row in set (21.83 sec)

1 个答案:

答案 0 :(得分:0)

此构造浪费了一些时间:

SELECT COUNT(*)
    FROM ( SELECT lots-of-columns
               FROM, etc )

不仅仅是简单地

           SELECT COUNT(*)
               FROM, etc

这是因为已建立派生表并将其放入临时表中(可能是您的情况下放在磁盘上),然后进行计数。

由于我没有在MariaDB的EXPLAIN中看到“ 2”,所以我猜测他们为您做了优化。

在5.6和10.0时,他们在优化器中出现了一些明显的差异。您遇到了MariaDB大放异彩的情况。

将第一个CASE..END简化为IFNULL(i.FLOW_DEFINE, 'free');等

请使用JOIN..ON而不是逗号+ WHERE-这不会提高速度,但可能有助于提高可读性。

即使在子查询中,也有其他简化;例如,CASE对COUNT不提供任何服务。无论您是否在乎,如果您提供了一个最小的测试案例来证明问题所在,那么我们可能会提供更多帮助。