优化派生子查询的性能,将不同的记录拖入group_concat()

时间:2018-11-19 15:58:09

标签: sql mariadb query-performance

在此查询中 https://www.db-fiddle.com/f/wi525XMRAff2GHUrBpWAM8/5

select x.`id`, (
  select
    group_concat(d.`content`)
  from (
    select
      docs.`content`
    from
      `docs`
    where
      docs.`x_id` = 1
    group by
      docs.`content`
   ) as `d`
) as `letters`
from `x`
where x.`id` = 1;

应该从 x.id 中拉出 x table ,并从中拉出 docs table 使用 docs.x_id 链接一次,这就是为什么我使用静态 x.id = 1

docs table 中的字母可以复制为同一 x_id ,因此我想清楚地将其拉出,所以我走了< strong>标量查询,但是查询可以进一步优化吗?

我正在使用最新的 mariadb 版本,并给我 extra: Using index; Using temporary; Using filesort ,而不是小提琴中显示 extra: Using index condition; Using temporary


我还尝试使用此查询 https://www.db-fiddle.com/f/wi525XMRAff2GHUrBpWAM8/4

select x.`id`, group_concat(d.`content`) as `letters`
from `x`
inner join (
  select
    d.`x_id`, d.`content`
  from
    `docs` d
  where
    d.`x_id` = 1
  group by
    d.`x_id`, d.`content`
) d ON d.`x_id` = 1
where x.`id` = 1;

它为 mysql 8 提供了更好的执行计划结果,但是在 mariadb(mysql 5.5.5)上,它与第一个查询的结果相同

2 个答案:

答案 0 :(得分:1)

我会尝试:

select x.`id`, 
       (select group_concat(distinct d.`content`)
        from docs
        where docs.`x_id` = 1
       ) as `letters`
from `x`
where x.`id` = 1;

答案 1 :(得分:1)

更简单:

SELECT  1 AS id,
        GROUP_CONCAT(DISTINCT content) AS letters
    FROM  docs
    WHERE  x_id = 1

但是,我怀疑您过分简化了查询。因此,这种简化可能无法完全应用。

无论如何,请尽量不要将“子查询”视为解决问题的方法。请注意,您是如何需要2个子查询的,但是我是在0中完成的。它可能快得多。

为进一步提高速度,请将INDEX(x_id)更改为INDEX(x_id, content)

“使用文件排序”和“使用临时”不是世界末日。在某些查询中,它们是绝对必要的。此外,“文件排序”通常在RAM中完成;拍摄此查询时没有磁盘受伤。我认为我的查询 INDEX还是避免使用它们。

警告:GROUP_CONCAT上的默认限制为1024。参见group_concat_max_len