mysql 以优化的方式查询“最新订单”

vhmi4jdf  于 2023-03-07  发布在  Mysql
关注(0)|答案(2)|浏览(105)

(MySQL,InnoDB)数据库有表Client (id, name)Order (id, client_id, name, order_date)。我想查询他们接收Client和 * 一个,最新的 * Order为每个客户端的列表,或没有,如果没有为该客户端(左连接)。
在选定的行上还有其他约束、连接和列,但是它们不应该妨碍客户端顺序连接,因为客户端顺序连接是直接的。
问题是,即使有约束,它也要从总共100 000+行的选择中选择1000+行,并且需要15+分钟才能返回。当我尝试将其导出到CSV文件时,甚至在一个小时后它都无法完成。
以下是我的尝试:

SELECT DISTINCT Client.id as client_id, 
Client.name as client_name,
Order.name as order FROM Client
LEFT JOIN Order on Order.id = (
    SELECT O2.id FROM Order O2
    <... joins and clauses for side tables ...>
    WHERE O2.orderDate >= '2021-01-01' and  O2.orderDate <= '2022-01-01'
    AND O2.client_id = Client.id
    ORDER BY O2.id DESC
    LIMIT 1
    )
<... joins and clauses for side tables ...>;

我在谷歌上搜索过,发现子查询效率很低,那么有没有一种方法可以在没有子查询的情况下和/或以一种更有效的方式查询呢?
编辑:我正在使用MySQL8和DBeaver 22.2.2。简单地查询数据并输出到DBeaver窗口需要大约11分钟。如果我然后右键单击它并选择"导出",问题就开始了。

p4rjhz4m

p4rjhz4m1#

我将使用CTE提取每个客户端的最新订单,然后查询该订单

WITH clients_last_order (client_id, order_date) AS (
  SELECT client_id, MAX(order_date)
  FROM Orders
  GROUP BY client_id
)
SELECT Clients.id, Clients.name, Orders.id, Orders.order_date
FROM Clients
LEFT JOIN Orders ON (Clients.id = Orders.client_id)
LEFT JOIN clients_last_order ON (
  Orders.client_id = clients_last_order.client_id
  AND Orders.order_date = clients_last_order.order_date
)
zfciruhq

zfciruhq2#

我将使用左连接来提取最大日期,然后获得该记录的ID,以便再次与订单连接。

    • 元数据**
-- create a table
    CREATE TABLE Client (
      id INTEGER PRIMARY KEY,
      name NVARCHAR(100) NOT NULL
    );
    
    CREATE TABLE Orders(
    id int PRIMARY KEY,
    client_id INTEGER,
    name NVARCHAR(100),
    order_date DATETIME,
    foreign key (client_id) references Client(id)
    );
    INSERT INTO Client VALUES (1, 'Ryan');
    INSERT INTO Client VALUES (2, 'Joanna');
    INSERT INTO Client VALUES (3, 'Sbira');
    INSERT INTO Client VALUES (4, 'Jamal');
    
    
    INSERT INTO Orders VALUES (1, 1,'Burger', '2023-03-06');
    INSERT INTO Orders VALUES (2, 1,'Burger', '2023-03-07');
    INSERT INTO Orders VALUES (3, 1,'Burger', '2023-03-09');
    
    
    
    INSERT INTO Orders VALUES (4, 2,'Bag', '2023-03-06');
    INSERT INTO Orders VALUES (5, 2,'Tomatoes', '2023-03-07');
    INSERT INTO Orders VALUES (6, 2,'Spaghetti', '2023-03-10');
    
    INSERT INTO Orders VALUES (7, 3,'Screen', '2023-03-06');
    INSERT INTO Orders VALUES (8, 3,'Salad', '2023-03-07');
    INSERT INTO Orders VALUES (9, 3,'Cheese', '2023-03-11');

    /*Extraction script*/
    
    SELECT C.name,
           Orders.name,
           Orders.order_date
      FROM Client C
      LEFT JOIN (   SELECT o.client_id AS cid,
                           MAX(order_date) AS last_order
                      FROM Orders o
                     group by o.client_id) Orders_bis
        ON Orders_bis.cid   = C.id
      LEFT JOIN Orders
        ON order_date       = Orders_bis.last_order
       AND Orders.client_id = Orders_bis.cid
    • 产出**
    • 客户订单订单日期**

瑞安|汉堡包|2023年3月9日00时00分
乔安娜|意大利面|2023年3月10日00时00分
斯比拉|奶酪2023年3月11日00:00:00
Jamal空空

相关问题