加入视图时查询性能降低

时间:2016-10-09 12:07:45

标签: mysql query-performance sqlperformance

我有两张桌子:

describe CONSUMO

Field       Type        Null    Key     Default     Extra
idconsumo   int(11)     NO      PRI     NULL        auto_increment
idkey       int(11)     NO      MUL     NULL    
ip          varchar(50) NO              Unknown 
fechahora   datetime    NO              NULL    


describe CONTRATADO

Field       Type        Null    Key     Default     Extra
idkey       int(11)     NO      PRI     NULL        auto_increment
idusuario   int(11)     NO      MUL     NULL    
idproducto  int(11)     NO      MUL     NULL    
key         varchar(64) NO      MUL     NULL    
descripcion varchar(50) YES             "API KEY"   
peticiones  int(11)     YES             NULL    
caducidad   datetime    YES             NULL    

一个视图(返回NOW()的最后30天):

CREATE VIEW `last_30_days` AS
    SELECT 
        DATE_FORMAT((NOW() - INTERVAL ((`units`.`i` + (`tens`.`i` * 10)) + (`hundreds`.`i` * 100)) DAY),
                '%M %e') AS `fecha`,
        DATE_FORMAT((NOW() - INTERVAL ((`units`.`i` + (`tens`.`i` * 10)) + (`hundreds`.`i` * 100)) DAY),
                '%Y%m%d') AS `fecha_order`
    FROM
        ((`0_9_range` `units`
        JOIN `0_9_range` `tens`)
        JOIN `0_9_range` `hundreds`)
    WHERE
        ((NOW() - INTERVAL ((`units`.`i` + (`tens`.`i` * 10)) + (`hundreds`.`i` * 100)) DAY) BETWEEN (NOW() - INTERVAL 1 MONTH) AND NOW())

每当我运行查询时,例如:

SELECT sub1.fecha, COUNT(idconsumo) as consumo
FROM `last_30_days` `sub1`
LEFT JOIN `CONSUMO` ON sub1.fecha = DATE_FORMAT(fechahora, "%M %e")
LEFT JOIN `CONTRATADO` ON CONSUMO.idkey = CONTRATADO.idkey
WHERE idusuario IS NULL OR idusuario = 1
GROUP BY `sub1`.`fecha`
ORDER BY `sub1`.`fecha_order`

需要相当长的时间(约20秒)。

以下是对查询的解释:

id      select_type     table                                   type    possible_keys   key     key_len ref                     rows    Extra
1       PRIMARY         <derived3>                              ALL     NULL            NULL    NULL    NULL                    10      "Using temporary; Using filesort"
1       PRIMARY         <derived13>                             ALL     NULL            NULL    NULL    NULL                    10      "Using join buffer"
1       PRIMARY         <derived23>                             ALL     NULL            NULL    NULL    NULL                    10      "Using where; Using join buffer"
1       PRIMARY         CONSUMO                                 ALL     NULL            NULL    NULL    NULL                    908553  
1       PRIMARY         CONTRATADO                              eq_ref  PRIMARY         PRIMARY 4       c1geoapi.CONSUMO.idkey  1       "Using where"
23      DERIVED         NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
24      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
25      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
26      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
27      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
28      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
29      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
30      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
31      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
32      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
NULL    "UNION RESULT"  <union23,24,25,26,27,28,29,30,31,32>    ALL     NULL            NULL    NULL    NULL                    NULL    
13      DERIVED         NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
14      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
15      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
16      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
17      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
18      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
19      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
20      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
21      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
22      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
NULL    "UNION RESULT"  <union13,14,15,16,17,18,19,20,21,22>    ALL     NULL            NULL    NULL    NULL                    NULL    
3       DERIVED         NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
4       UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
5       UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
6       UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
7       UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
8       UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
9       UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
10      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
11      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
12      UNION           NULL                                    NULL    NULL            NULL    NULL    NULL                    NULL    "No tables used"
NULL    "UNION RESULT"  <union3,4,5,6,7,8,9,10,11,12>           ALL     NULL            NULL    NULL    NULL                    NULL    

为了改善查询,我该怎么办?为什么需要这么长时间?

1 个答案:

答案 0 :(得分:1)

大多数问题都在这里:

LEFT JOIN `CONSUMO` ON sub1.fecha = DATE_FORMAT(fechahora, "%M %e")

特别是:

  • 不要使用LEFT;你想要所有的行,没有额外的行,对吗?因此,请使用普通JOIN

  • 执行索引fechahora

  • 不要使用DESCRIBE;它的描述性低于SHOW CREATE TABLE

  • 而不是一遍又一遍地重新计算过去30天;有一个包含几年日期值的长表,并使用WHERE子句来限制所需的行。

  • 不要在函数中隐藏fechahora。重新排列查询,使其看起来像

    ON fechahora&gt; = ... sub1.fecha ... 和fechahora&lt; ... sub1.fecha + INTERVAL 1 DAY ...

...需要做出与“%M%e”相反的任何操作。您可能最好更改last_30_days以计算普通DATE数据类型。如果/当您需要输出中的特定格式时,请在SELECT

中执行此操作