mysql - 如何使用索引改进我的sql select?

标签 mysql sql database indexing innodb

我需要有关 sql select 的帮助。 MySQL 5.7版本

这是我的 table

create table if not exists OffersDayReport
(
    id int auto_increment
        primary key,
    aff_id int not null,
    aff_manager_id int not null,
    source text null,
    adv_id int not null,
    adv_manager_id int not null,
    offer_id int not null,
    offer_category_id int not null,
    country char(2) null,
    browser varchar(255) null,
    deviceType varchar(255) null,
    deviceOS varchar(255) null,
    preLander varchar(11) null,
    goal int null,
    offerPage int null,
    visits int not null,
    clicks int not null,
    conversions int not null,
    payoutInUSD decimal(10,2) not null,
    revenueInUSD decimal(10,2) not null,
    profitInUSD decimal(10,2) not null,
    brokenRevenueInUSD decimal(10,2) not null,
    time int not null,
    constraint unique_row
        unique (time, aff_id, offer_id, source, country, browser, deviceType, deviceOS, preLander, goal, offerPage)
)
charset=utf8;

这是一个 select 的示例:

SELECT OffersModel.lead                                                     as default_lead,
       OffersDayReport.offer_id                                             as report_title_offer_id,
       OffersModel.name                                                     as offers_name,
       sum(OffersDayReport.visits)                                          as report_title_visits,
       sum(OffersDayReport.clicks)                                          as report_title_clicks,
       sum(OffersDayReport.conversions)                                     as report_title_conversions,
       sum(OffersDayReport.payoutInUSD)                                     as report_title_payout,
       sum(OffersDayReport.revenueInUSD)                                    as report_title_revenue,
       sum(OffersDayReport.profitInUSD)                                     as report_title_profit,
       sum(OffersDayReport.conversions) / sum(OffersDayReport.clicks) * 100 as report_title_CR
FROM OffersDayReport
         LEFT OUTER JOIN Offers as OffersModel ON OffersModel.id = OffersDayReport.offer_id
WHERE OffersDayReport.aff_manager_id IN ({numbers})
  AND OffersDayReport.time >= {some start time}
  AND OffersDayReport.time <= {some end time}
GROUP BY OffersDayReport.offer_id;

范围可以是 1 天和 6 个月。 where 子句的可变性可能不同 - 使用 aff_manager_idadv_manager_id 或两者等。

所有行的数量很大 - 大约 1000 亿。 现在我的选择大约需要 3-4 分钟,有时会达到 10 分钟。 我尝试了不同类型的索引,但 mysql 分析器宁愿不使用它们。 即使我使用 FORCE INDEX() - 我尝试过的所有类型的索引,也只会让我的选择缓慢。

最佳答案

确保您有正确的复合索引

  table  OffersDayReport  columns (time, aff_manager_id )

对于 Offers 表,您可以使用冗余复合索引(从索引中检索所有值) 用于过滤值并避免访问表数据

  table Offers columns  ( id, name, lead)

最后您可以尝试使用内部联接更改 IN 子句..

另一个可能的改进可以通过更改 INNER JOIN 中的 IN 子句来获得。这是因为 IN 子句与多个 OR 子句相同,而 INNER JOIN 只执行一次。 为此

如果 ({numbers}) 来自子查询,您可以尝试使用

  FROM OffersDayReport
  INNER JOIN  (
    select your_id
    from your_table
    .....
  ) t on t.your_id =  OffersDayReport.aff_manager
  LEFT OUTER JOIN Offers as OffersModel ON OffersModel.id = OffersDayReport.offer_id
  WHERE OffersDayReport.time >= {some start time}
  AND OffersDayReport.time <= {some end time}

否则,如果查询未获得 ({numbers}),您可以使用并集构建等效结果

  select  numbers1 numbers
  UNION
  select  numbers2 
  UNION 
  select  numbers3
  .....
  UNION 
  select  numbersN

以及查询

   FROM OffersDayReport
  INNER JOIN  (
    select  numbers1 my_number
    UNION
    select  numbers2 
    UNION 
    select  numbers3
    .....
    UNION 
    select  numbersN
  ) t on t.my_number =  OffersDayReport.aff_manager
  LEFT OUTER JOIN Offers as OffersModel ON OffersModel.id = OffersDayReport.offer_id
  WHERE OffersDayReport.time >= {some start time}
  AND OffersDayReport.time <= {some end time}

关于mysql - 如何使用索引改进我的sql select?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59320682/

相关文章:

php - MySQL 查询 SELECT a.foo AS bar - 多个?

mysql - 正确的mysql(关系型)数据库设计结构是什么

python - 在 cron 中引用 ini 文件失败

android - 使用 json 通过服务器数据库绘制折线图

php - 用于访问 Drupal 7 中数据字段的简单 mysql 查询

mysql - 当前密码未知时重置 MySQL root 密码

mysql - MySQL中的空IN子句参数列表

java - 执行SQL语句时出现语法错误

MySQL Not Null 命令没有执行任何操作

php - 我知道我的表包含行,但我的查询返回结果为 0。如何修复此问题?