SQL - 加入查询运行缓慢

时间:2015-10-14 16:17:10

标签: mysql sql database database-design

我正在尝试从3个不同的表中获取数据,如下所示:

SELECT urs.id
    ,urs.username
    ,urs.b_avg_update
    ,urs.b_set_min_avg
    ,urs.b_set_max_avg
    ,urs.b_min_avg
    ,urs.b_max_avg
    ,trs.TIME
    ,trs.user
    ,sum(trs.amount)
    ,trs.type
    ,ur.user_by
FROM (
    SELECT DISTINCT user_by
    FROM xeon_users_rented
    ) AS ur
LEFT JOIN users AS urs ON ur.user_by = urs.username
LEFT JOIN transactions AS trs ON urs.id = trs.user
    AND trs.type = 'Recycle'
    AND trs.TIME >= UNIX_TIMESTAMP(CURDATE())
GROUP BY ur.user_by

但是,该查询运行速度很慢:

Showing rows 0 - 29 (812 in total, request took 15.0095 sec)

在上述查询中运行EXPLAIN时,这就是我得到的:

id  select_type table   type    possible_keys   key key_len ref rows    Extra   
1   PRIMARY <derived2>  ALL NULL    NULL    NULL    NULL    1516    Using temporary; Using filesort
1   PRIMARY urs ALL NULL    NULL    NULL    NULL    14553   Using where; Using join buffer (flat, BNL join)
1   PRIMARY trs ref user,type   user    8   littlebu_maindb.urs.id  6   Using where
2   DERIVED xeon_users_rented   range   NULL    idx_user_by 62  NULL    1516    Using index for group-by

我试图在某些列上添加INDEXES,希望能加快速度:

在表格xeon_users_rented上:

Table   Non_unique  Key_name    Seq_in_index    Column_name Collation   Cardinality Sub_part    Packed  Null    Index_type  
xeon_users_rented   0   PRIMARY 1   id  A   37897   NULL    NULL        BTREE       
xeon_users_rented   0   user    1   user    A   37897   NULL    NULL        BTREE       
xeon_users_rented   1   user_by 1   user_by A   1579    NULL    NULL        BTREE       
xeon_users_rented   1   since   1   since   A   4210    NULL    NULL        BTREE       
xeon_users_rented   1   expire  1   expire  A   7579    NULL    NULL        BTREE       
xeon_users_rented   1   clicks  1   clicks  A   176 NULL    NULL        BTREE       
xeon_users_rented   1   clicks_last 1   clicks_last A   5413    NULL    NULL        BTREE       
xeon_users_rented   1   avg 1   avg A   3445    NULL    NULL        BTREE       
xeon_users_rented   1   click_hour  1   click_hour  A   46  NULL    NULL        BTREE       
xeon_users_rented   1   click_minute    1   click_minute    A   102 NULL    NULL        BTREE       
xeon_users_rented   1   idx_click_hour  1   click_hour  A   46  NULL    NULL        BTREE       
xeon_users_rented   1   idx_click_minute    1   click_minute    A   112 NULL    NULL        BTREE       
xeon_users_rented   1   idx_id  1   id  A   37897   NULL    NULL        BTREE       
xeon_users_rented   1   idx_user    1   user    A   37897   NULL    NULL        BTREE       
xeon_users_rented   1   idx_user_by 1   user_by A   1515    NULL    NULL        BTREE       
xeon_users_rented   1   idx_expire  1   expire  A   6316    NULL    NULL        BTREE       
xeon_users_rented   1   idx_since   1   since   A   4210    NULL    NULL        BTREE       
xeon_users_rented   1   idx_clicks  1   clicks  A   176 NULL    NULL        BTREE       
xeon_users_rented   1   idx_clicks_last 1   clicks_last A   5413    NULL    NULL        BTREE       
xeon_users_rented   1   idx_avg 1   avg A   3445    NULL    NULL        BTREE       

在表格users上:

Table   Non_unique  Key_name    Seq_in_index    Column_name Collation   Cardinality Sub_part    Packed  Null    Index_type  
users   0   PRIMARY 1   id  A   14554   NULL    NULL        BTREE       
users   1   idx_username    1   username    A   14554   NULL    NULL        BTREE       
users   1   upline  1   upline  A   856 NULL    NULL        BTREE       
users   1   upline  2   upline_expire   A   856 NULL    NULL        BTREE

最后但并非最不重要的是transactions表:

Table   Non_unique  Key_name    Seq_in_index    Column_name Collation   Cardinality Sub_part    Packed  Null    Index_type  
transactions    0   PRIMARY 1   id  A   5293    NULL    NULL        BTREE       
transactions    1   user    1   user    A   882 NULL    NULL        BTREE       
transactions    1   type    1   type    A   9   NULL    NULL        BTREE       
transactions    1   amount  1   amount  A   378 NULL    NULL        BTREE

我看不出导致缓慢的原因。总共甚至没有1000条记录。 如何改进原始查询和/或数据库设计?

2 个答案:

答案 0 :(得分:1)

以这种方式试试。我认为users应该是JOIN LEFT侧的SELECT urs.username ,sum(trs.amount) FROM users AS urs LEFT JOIN xeon_users_rented AS ur ON urs.username = ur.user_by LEFT JOIN transactions AS trs ON urs.id = trs.user AND trs.type = 'Recycle' AND trs.TIME >= UNIX_TIMESTAMP(CURDATE()) WHERE ur.user_by IS NOT NULL GROUP BY ur.user_by 。但如果那不是您正在寻找的查询,我会尝试别的。

lib/myapp/Controller/*

答案 1 :(得分:0)

通常,这些类型的查询可以使用相关子查询而不是外层group by来更快地运行。您正在从transactions中提取任意字段,因此我假设您只需要amount。那username是独一无二的。然后您可以将查询编写为:

SELECT u.*,
       (SELECT sum(trs.amount)
        FROM transactions trs
        WHERE u.id = trs.user AND trs.type = 'Recycle' AND
              trs.TIME >= UNIX_TIMESTAMP(CURDATE())
       ) as amt
FROM (SELECT DISTINCT user_by
      FROM xeon_users_rented
     ) AS xur JOIN
     users u
     ON xur.user_by = u.username;

然后,users(username)transactions(user, type, time, amount)上的索引最适合此查询。