【问题标题】:MySQL query is very slowMySQL查询很慢
【发布时间】:2016-04-11 17:36:06
【问题描述】:

我有一个包含 1500 万到 2000 万行的 MySql 表。过去,我使用数据分区将性能提高了 100% 以上。但是,现在,当我运行以下查询时,queru 需要 60 多秒才能执行。

select state, gender, count(*) from big_data where gender in ('Sugar Daddy','Sugar Baby') group by state, gender

结果

[SQL]select state, gender, count(*) from big_data where gender in ('Sugar Daddy','Sugar Baby') group by state, gender

Affected rows: 0
Time: 59.390s

在我找到的解释中: 99% 的时间都花在复制到临时表上!如何提高此查询的性能?

架构和解释:

【问题讨论】:

  • 肯定使用 IN 会很慢,因为它必须进行多次评估。特别是在字符串类型列上。你不能用其他方式继续吗?你的表上定义了索引吗?
  • 您需要索引(性别、州)。请发布表架构和解释结果。
  • 是的,索引已定义。
  • 好的,哇。当我将“in”替换为“从 big_data 中选择 state、gender、count(*) where gender='Sugar Daddy' group by state,gender”时,它将时间从 65 秒减少到 27 秒
  • SHOW CREATE TABLE big_data 的结果会更好。

标签: mysql temp-tables bigdata


【解决方案1】:

由于IN 实际上是一个转义的OR 列表,您可以尝试使用UNION 来利用gender 上的索引;像这样:

select state, gender, count(*) 
from big_data 
where gender = 'Sugar Daddy' 
group by state
UNION
select state, gender, count(*) 
from big_data 
where gender  = 'Sugar Baby' 
group by state
order by state, gender

【讨论】:

    【解决方案2】:

    您至少需要gender 列上的索引,因此它可以用于 WHERE 子句。但是,如果有太多行匹配 WHERE 条件,GROUP BY 的排序可能也很昂贵。因此,(性别,状态)上的索引会更好,您的查询将只操作该索引。由于state 已经是 PK 的一部分,因此该索引甚至不会占用更多空间,因为 PK 始终是 InnoDB 中任何索引的一部分。

    另外我建议你创建一个genders 表(gender_id,gender_name),并在你的大表上使用一个外键引用genders.gender_id。这就是你保持表格和索引更小的原因。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-15
      • 1970-01-01
      • 1970-01-01
      • 2014-09-17
      • 2013-08-14
      • 2014-08-02
      • 2018-09-07
      • 1970-01-01
      相关资源
      最近更新 更多