gpt4 book ai didi

mysql - Rails/MySQL : Group/Distinct doubles query time using LEFT JOINS/slow performance

转载 作者:行者123 更新时间:2023-11-29 10:50:50 28 4
gpt4 key购买 nike

我有一个(有点)复杂的查询,返回 60K 多条客户记录。我有两个左外连接,需要与查询一起使用来搜索关联记录:

customers = customers.
left_outer_joins(:phones, :emails).
select("customers.id, customers.name, ...")

if params[:sSearch].present?
params[:sSearch] = parse_phone_number(params[:sSearch])

customers = customers.where(
"customers.name like :search OR
..
phones.number like :search OR
emails.email like :search",
search: "%#{params[:sSearch]}%"
)
end

customers = customers.
group('customers.id').
order("#{sort_column} #{sort_direction}).
page(page).
per(per_page)

(注意:这在数据表 ajax 调用中使用,因此 sort_column、sort_direction、page 和 per_page 都是其参数。)

我的所有索引都已排好。

这是我面临的主要问题:如果我不使用 group('customers.id'),由于左外连接,它将返回重复的客户记录。但添加 group 子句似乎会使查询时间增加至少 2 倍。在查询末尾使用 .distinct 似乎比使用 group 还要慢一点。

是否有更好/更快的方法来不返回具有左外连接的重复项而不显着增加查询时间?目前这需要超过 1000 毫秒。

编辑:为了回答下面影子的评论 - 我正在加入多个电话/电子邮件,因为我需要搜索它们。我期望的是,如果客户记录与搜索匹配(假设在已连接的手机上),它只会返回一个客户 - 而不是两个。

最佳答案

如果您只想搜索地址/电话号码,但不想显示它们,请使用带有子查询的存在运算符而不是联接。

sql 中的代码如下所示:

select *
from customers c
where c.name like '%...%'
or exists (select 1 from emails e where e.email like '%...%' and e.customer_id=c.id) ...

但是,如果您确实想显示地址和电话号码,则必须使用联接。在这种情况下,您可能需要使用 MySQL 的内置 group_concat() 函数将各种地址和电话号码连接成一个值。

其他需要考虑的事情:

  1. 使用union代替一系列or条件
  2. 尽可能尝试使用全文索引和搜索,而不是 like,因为 like '%...%' 过滤器无法使用索引来加速查询。

关于mysql - Rails/MySQL : Group/Distinct doubles query time using LEFT JOINS/slow performance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43762469/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com