MySQL - 如何优化此查询?

Bre*_*ett 5 mysql sql performance query-optimization

以下查询有效,但10个记录(2秒)非常慢.该分析说它创建了一个tmp表,但我不确定为什么.

基本上,我加入当前用户,加入acl组,获取他们所在的所有组,然后加入团队到公司,获得他们所在的所有公司,然后加入公司订单,获得所有订单..

如果我删除此行

ORDER BY orders.created_on DESC 
Run Code Online (Sandbox Code Playgroud)

然后查询执行0.06秒(更可接受)..

帮助,关于如何优化的任何想法?非常感谢 :)

SELECT
    orders.uuid,
    companies.name as company_name
FROM
    users u
JOIN    
    users_acl_groups g on   u.uuid = g.user_uuid
JOIN
    users_acl acl on (acl.user_uuid = u.uuid or acl.group_uuid = g.group_uuid) 
JOIN 
    companies on acl.item_uuid = companies.uuid
JOIN
    orders on companies.uuid = orders.company_uuid
WHERE
    u.uuid = 'DDEC8073-5056-C000-01ED583A51CBCA32' and orders.status <> ''
ORDER BY orders.created_on DESC 

limit 0, 10;
Run Code Online (Sandbox Code Playgroud)

更新,查询的解释..

1 SIMPLE命令ALL 9403使用临时; 使用filesort

1 SIMPLE acl ALL 1859使用where; 使用连接缓冲区

1 SIMPLE g ALL 2005使用where; 使用连接缓冲区

1 SIMPLE公司eq_ref PRIMARY PRIMARY 52 table.orders.company_uuid 1

1 SIMPLE u ALL 33595使用where; 不同; 使用连接缓冲区

Bil*_*win 2

您是否考虑过进行事实表样式设计,作为非规范化步骤?

基本上它是一种多对多交集表,例如:

CREATE TABLE user_order_fact (
  user_uuid ...
  order_uuid ...
  order_created_on ...
  order_status ...
  company_name ...,
  primary key (user_uuid, order_uuid),
  key (user_uuid, order_status, order_created_on, order_uuid, company_name)
);

... fill with data ...

SELECT
    order_uuid,
    company_name
FROM
    user_order_fact
WHERE
    user_uuid = 'DDEC8073-5056-C000-01ED583A51CBCA32' and order_status <> ''
ORDER BY order_created_on DESC 

limit 0, 10;
Run Code Online (Sandbox Code Playgroud)

我猜的是复合指数。你必须不断尝试,直到成功为止。基本上,您正在尝试让优化器计划报告它正在使用索引

当然,这是以非规范化形式冗余存储数据,因此您需要设置一些触发器以使其与规范化表保持同步。