【问题标题】:MySQL query taking too long to finishMySQL 查询需要很长时间才能完成
【发布时间】:2015-06-05 02:42:41
【问题描述】:

我正在使用 MySQL 数据库和以下查询:

SELECT
    customer_id,
    customer_code, 
    customer_name,  
    customer_address,
    customer_home_town
FROM  
    customers
    INNER JOIN (
        SELECT 
            issue_entry_customer_id,
            SUM(issue_entry_copies
              +issue_entry_subscribe
              +issue_entry_freecopies) AS col_copies 
        FROM 
            issue_entry 
        WHERE 
            issue_entry_deleted_status = 0  AND
            DATE_FORMAT(issue_entry_date,'%Y-%m') 
                = '".dateDatabaseFormat($issue_date)."'     
        GROUP BY 
            issue_entry_customer_id
    ) col_table 
        ON issue_entry_customer_id = customer_id
            AND customer_code = 1
            AND col_table.col_copies != 0
    ORDER BY
        customer_id ASC

issue_entry 表有超过 500 000 行。

如何提高性能?

【问题讨论】:

  • 只有完整的查询

标签: mysql database


【解决方案1】:
table_name alias INNER JOIN table_name2 alias ON ... 

这就是 INNER JOIN 查询的方式。为什么要在 INNER JOIN 语句之后进行选择?

【讨论】:

    【解决方案2】:

    这是您的查询:

    SELECT c.customer_id, c.customer_code, c.customer_name, 
           c.customer_address, c.customer_home_town
    FROM customers c INNER JOIN
          (SELECT issue_entry_customer_id, 
                  SUM(issue_entry_copies + issue_entry_subcripe + issue_entry_freecopies
                  ) AS col_copies 
           FROM issue_entry ie
           WHERE issue_entry_deleted_status = 0  AND
                 DATE_FORMAT(issue_entry_date, '%Y-%m')  = '".dateDatabaseFormat($issue_date)."'                 
          GROUP BY issue_entry_customer_id
         ) col_table
         ON col_table.issue_entry_customer_id = c.customer_id AND
            c.customer_code = 1 AND
            col_table.col_copies <> 0  
    ORDER BY c.customer_id ASC;
    

    我的建议是更改查询的整个格式:

    SELECT c.customer_id, c.customer_code, c.customer_name, 
           c.customer_address, c.customer_home_town
    FROM customers c
    WHERE c.customer_code = 1 AND
          EXISTS (SELECT 1
                  FROM issue_entry ie
                  WHERE ie.issue_entry_customer_id = customer_id AND  
                        DATE_FORMAT(issue_entry_date, '%Y-%m')  = '".dateDatabaseFormat($issue_date)."' AND
                        ie.issue_entry_deleted_status = 0 AND
                        (issue_entry_copies > 0 OR
                         issue_entry_subcripe > 0 OR
                         issue_entry_freecopies
                        )
                 )
    ORDER BY customer_id ASC;
    

    注意:这假设三列永远不会是负数。

    对于此查询,您需要以下索引:customers(customer_code, customer_id)issue_entry(issue_entry_customer_id, issue_entry_deleted_status)

    【讨论】:

      【解决方案3】:

      您的查询使用了一些别名以获得更好的可读性。

      select
      c.customer_id, 
      c.customer_code, 
      c.customer_name,  
      c.customer_address,
      c.customer_home_town
      from customers c
      inner join (
       SELECT 
       issue_entry_customer_id, 
       SUM(issue_entry_copies+issue_entry_subcripe+issue_entry_freecpoies) AS col_copies 
       FROM issue_entry 
       WHERE 
       issue_entry_deleted_status = 0  AND
       DATE_FORMAT(issue_entry_date,'%Y-%m') = '".dateDatabaseFormat($issue_date)."'                 
       GROUP BY 
       issue_entry_customer_id
      )x
      on x.issue_entry_customer_id = c.customer_id
      and c.customer_code   = 1
      and x.col_copies != 0  
      order BY customer_id ASC
      

      现在对于大数据,您当然需要添加一些索引来提升查询。

      alter table issue_entry add index i_del_date(issue_entry_deleted_status,issue_entry_date);
      alter table issue_entry add index i_cid_idx(issue_entry_customer_id);
      alter table customers add index c_code_idx(customer_code);
      

      如果客户表中的customer_id 不是主键,您可能还需要对其进行索引

      alter table customers add index c_customer_id_idx(customer_id);
      

      另请注意,即使 issue_entry_date 被编入索引,它也可能无法使用索引,因为您正在格式化日期。

      确保在应用索引之前备份表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-27
        • 1970-01-01
        • 1970-01-01
        • 2014-01-15
        • 1970-01-01
        • 1970-01-01
        • 2018-02-07
        • 2016-07-30
        相关资源
        最近更新 更多