mysql - 我怎样才能加快sql查询?

标签 mysql

假设有两个表:

事件:


+-------------------+--------------+------+-----+-------------------+-----------------------------+
| Field             | Type         | Null | Key | Default           | Extra                       |
+-------------------+--------------+------+-----+-------------------+-----------------------------+
| id                | int(11)      | NO   | PRI | NULL              | auto_increment              |
| campaign_id       | varchar(64)  | YES  | UNI | NULL              |                             |
| account_id        | varchar(64)  | YES  | MUL | NULL              |                             |
| name              | blob         | YES  |     | NULL              |                             |
| objective         | varchar(64)  | YES  |     | NULL              |                             |
| can_use_spend_cap | tinyint(2)   | YES  |     | NULL              |                             |
| status            | varchar(64)  | YES  |     | NULL              |                             |
| spend_cap         | bigint(14)   | YES  |     | 0                 |                             |
| effective_status  | char(128)    | YES  |     | NULL              |                             |
| promoted_object   | text         | YES  |     | NULL              |                             |
| lifetime_budget   | bigint(14)   | YES  |     | NULL              |                             |
| daily_budget      | bigint(14)   | YES  |     | NULL              |                             |
| update_time       | timestamp    | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| create_time       | timestamp    | NO   | MUL | CURRENT_TIMESTAMP |                             |
| task_status       | tinyint(3)   | YES  |     | NULL              |                             |
| is_smb            | tinyint(3)   | YES  |     | NULL              |                             |
| rule_created      | tinyint(4)   | YES  |     | 0                 |                             |
| access_token      | varchar(255) | YES  | MUL | NULL              |                             |
+-------------------+--------------+------+-----+-------------------+-----------------------------+

和表 campaign_statistic

+---------------------------+---------------+------+-----+---------+----------------+
| Field                     | Type          | Null | Key | Default | Extra          |
+---------------------------+---------------+------+-----+---------+----------------+
| id                        | int(11)       | NO   | PRI | NULL    | auto_increment |
| campaign_id               | varchar(64)   | YES  | MUL | NULL    |                |
| account_id                | varchar(64)   | YES  |     | NULL    |                |
| impressions               | int(11)       | YES  |     | NULL    |                |
| clicks                    | int(11)       | YES  |     | NULL    |                |
| spend                     | decimal(14,6) | YES  |     | NULL    |                |
| cpc                       | decimal(14,6) | YES  |     | NULL    |                |
| cpm                       | decimal(14,6) | YES  |     | NULL    |                |
| cpp                       | decimal(14,6) | YES  |     | NULL    |                |
| ctr                       | decimal(14,6) | YES  |     | NULL    |                |
| cost_per_purchase         | decimal(14,6) | YES  |     | NULL    |                |
| cost_per_addtocart        | decimal(14,6) | YES  |     | NULL    |                |
| fb_pixel_addtocart        | int(11)       | YES  |     | NULL    |                |
| fb_pixel_addtocart_values | decimal(14,6) | YES  |     | NULL    |                |
| fb_pixel_purchase         | int(11)       | YES  |     | NULL    |                |
| fb_pixel_purchase_values  | decimal(14,6) | YES  |     | NULL    |                |
| roas                      | decimal(14,6) | YES  |     | NULL    |                |
| roi                       | decimal(14,6) | YES  |     | NULL    |                |
| dt                        | date          | YES  |     | NULL    |                |
+---------------------------+---------------+------+-----+---------+----------------+

我想加入这两个表,然后执行ordersearchtime_range 工作。

我已经尝试过这样的糟糕尝试:

EXPLAIN SELECT
    campaign.id AS id,
    campaign.campaign_id AS campaign_id,
    campaign.account_id AS account_id,
    campaign.daily_budget AS daily_budget,
    campaign.lifetime_budget AS lifetime_budget,
    campaign.name AS name,
    campaign.effective_status AS effective_status,
    campaign.daily_budget AS daily_budget,
    statistic.spend AS spend,
    statistic.clicks AS clicks,
    statistic.impressions AS impressions,
    statistic.spend AS spend,
    statistic.fb_pixel_addtocart AS fb_pixel_addtocart,
    statistic.fb_pixel_addtocart_values AS fb_pixel_addtocart_values,
    statistic.fb_pixel_purchase AS fb_pixel_purchase,
    statistic.fb_pixel_purchase_values AS fb_pixel_purchase_values,

    statistic.cpc AS cpc,
    statistic.ctr AS ctr,
    statistic.cpm AS cpm,
    statistic.cost_per_addtocart AS cost_per_addtocart,
    statistic.cost_per_purchase AS cost_per_purchase,
    statistic.roi AS roi,
    statistic.roas AS roas,
    campaign.rule_created AS rule_created,
    campaign.is_smb AS is_smb

    FROM `campaign` as campaign

    LEFT JOIN

    (SELECT

    campaign_id,
    SUM(impressions) AS impressions,
    SUM(clicks) AS clicks,
    ROUND(SUM(spend),2) AS spend,
    SUM(fb_pixel_addtocart) AS fb_pixel_addtocart,
    ROUND(SUM(fb_pixel_addtocart_values),2) AS fb_pixel_addtocart_values,
    ROUND(SUM(fb_pixel_purchase),2) AS fb_pixel_purchase,
    ROUND(SUM(fb_pixel_purchase_values),2) AS fb_pixel_purchase_values,

    ROUND(SUM(clicks)*100/SUM(impressions), 6) AS ctr,
    ROUND(SUM(spend)/SUM(clicks), 6) AS cpc,
    ROUND(SUM(spend)*1000/SUM(impressions), 6) AS cpm,

    ROUND(SUM( spend )/SUM(fb_pixel_addtocart), 6) AS cost_per_addtocart,
    ROUND(SUM( spend )/SUM(fb_pixel_purchase), 6) AS cost_per_purchase,

    ROUND(SUM( fb_pixel_purchase )/SUM(spend), 6) AS roi,
    ROUND(SUM( fb_pixel_purchase )/SUM(spend), 6) AS roas

    FROM `campaign_statistic` WHERE  dt BETWEEN 2019-07-08 AND 2019-07-08  GROUP BY  campaign_id) statistic

    ON statistic.campaign_id = campaign.campaign_id

    WHERE  campaign.account_id = 1000623940119431

    AND (campaign.campaign_id LIKE "%%" OR campaign.name LIKE "%%") ORDER BY id ASC                

它可以工作,但查询速度很慢,对不起,我是 mysql 的新手。

如何优化sql,加快查询速度?

非常欢迎任何评论。非常感谢。



update question:

使用时,我会使用SUMROUND 或其他函数进行计算。好像是

没有使用索引,查询速度更慢。为什么会这样?


1)

EXPLAIN 

SELECT  campaign_id

FROM `campaign_statistic` 

WHERE  dt >= '2019-03-01' AND dt <= '2019-03-31'  

GROUP BY  fb_campaign_id



+----+-------------+----------------------------+-------+--------------------+---------------+---------+------+--------+-----------------------------------------------------------+
| id | select_type | table                      | type  | possible_keys      | key           | key_len | ref  | rows   | Extra                                                     |
+----+-------------+----------------------------+-------+--------------------+---------------+---------+------+--------+-----------------------------------------------------------+
|  1 | SIMPLE      | campaign_statistic         | range | campaign_date,date | campaign_date | 4       | NULL | 567748 | Using where; Using index; Using temporary; Using filesort |
+----+-------------+----------------------------+-------+--------------------+---------------+---------+------+--------+-----------------------------------------------------------+


2) 

EXPLAIN 

SELECT campaign_id,
SUM(impressions) AS impressions

FROM `campaign_statistic` 

WHERE  dt >= '2019-03-01' AND dt <= '2019-03-31'  

GROUP BY  fb_campaign_id



+----+-------------+----------------------------+------+--------------------+------+---------+------+---------+----------------------------------------------+
| id | select_type | table                      | type | possible_keys      | key  | key_len | ref  | rows    | Extra                                        |
+----+-------------+----------------------------+------+--------------------+------+---------+------+---------+----------------------------------------------+
|  1 | SIMPLE      | campaign_statistic         | ALL  | campaign_date,date | NULL | NULL    | NULL | 1647182 | Using where; Using temporary; Using filesort |
+----+-------------+----------------------------+------+--------------------+------+---------+------+---------+----------------------------------------------+




最佳答案

首先,您的查询有一些明显的缺陷。它应该看起来像:

SELECT . . . 
FROM `campaign` as campaign LEFT JOIN
      (SELECT campaign_id,
              SUM(impressions) AS impressions,
              SUM(clicks) AS clicks,
              ROUND(SUM(spend),2) AS spend,
              SUM(fb_pixel_addtocart) AS fb_pixel_addtocart,
              ROUND(SUM(fb_pixel_addtocart_values),2) AS fb_pixel_addtocart_values,
              ROUND(SUM(fb_pixel_purchase),2) AS fb_pixel_purchase,
              ROUND(SUM(fb_pixel_purchase_values),2) AS fb_pixel_purchase_values,

              ROUND(SUM(clicks)*100/SUM(impressions), 6) AS ctr,
              ROUND(SUM(spend)/SUM(clicks), 6) AS cpc,
              ROUND(SUM(spend)*1000/SUM(impressions), 6) AS cpm,

              ROUND(SUM( spend )/SUM(fb_pixel_addtocart), 6) AS cost_per_addtocart,
              ROUND(SUM( spend )/SUM(fb_pixel_purchase), 6) AS cost_per_purchase,

              ROUND(SUM( fb_pixel_purchase )/SUM(spend), 6) AS roi,
              ROUND(SUM( fb_pixel_purchase )/SUM(spend), 6) AS roas
      FROM `campaign_statistic`
      WHERE dt BETWEEN '2019-07-08' AND '2019-07-08'
      GROUP BY campaign_id
     ) statistic
     ON statistic.campaign_id = campaign.campaign_id
WHERE campaign.account_id = 1000623940119431 AND
      (campaign.campaign_id LIKE '%%' OR campaign.name LIKE '%%') 
ORDER BY id ASC;

一个起点是campaign(account_id, campaign_id, name) 的索引。然后对于子查询,campaign_statistic(dt, campaign_id)

根据数据,您可能会发现“展开”聚合会更好。也就是说,先执行 JOIN,然后对两个表进行聚合。

关于mysql - 我怎样才能加快sql查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56944861/

相关文章:

mysql - 如何在MySQL中选择6个月的数据,分组在下个月的22日和21日之间

mysql - Drupal自定义表单获取并记录当前用户

java - mysql存储过程调用可以手动工作,但不能从java中调用

c# - 在 GridView 中,我的 Roe 未更新或删除

java - 值没有转储到表 temp_demo 中

mysql - 如何使用 BLOB 字段缩小 ibd 文件?

MySQL - 可以调用函数来执行触发器操作吗?

mysql 多表查询问题

Windows 8.1 Pro 64 位上的 MySQL 5.6.14 64 位连接问题

php - 我有这个 php/mysql/ajax 代码,我想在记录显示时添加淡入淡出效果