繁体   English   中英

SQL 查询很慢。 我怎样才能让它更快?

[英]SQL query is slow. How can I make it faster?

我有下表,它本质上是一个系统,可以告诉我谁在哪个房间:

CREATE TABLE customers
    (`cus_id` int PRIMARY KEY, `name` varchar(5), `driver_id` int)
;
    
INSERT INTO customers
    (`cus_id`, `name`, `driver_id`)
VALUES
    (1, 'bob', 11111),
    (2, 'james', 22222),
    (3, 'sam', 33333),
    (4, 'billy', 44444)
;


CREATE TABLE hotel_rooms
    (`hroom_id` int PRIMARY KEY, `name` varchar(10), `cus_id` int)
;
    
INSERT INTO hotel_rooms
    (`hroom_id`, `name`, `cus_id`)
VALUES
    (1, 'small room', 3),
    (2, 'big room', 1)
;


CREATE TABLE snapshots
    (`snapshot_id` int PRIMARY KEY, `hroom_id` int, FOREIGN KEY (hroom_id) REFERENCES hotel_rooms (hroom_id), `date_added` datetime)
;
    
INSERT INTO snapshots
    (`snapshot_id`, `hroom_id`, `date_added`)
VALUES
    (1, 1, '2020-01-12 12:43:13'),
    (2, 1, '2020-01-13 17:23:53'),
    (3, 2, '2020-01-19 07:34:01')
;


CREATE TABLE participants
    (`participant_id` int PRIMARY KEY, `snapshot_id` int, FOREIGN KEY (snapshot_id) REFERENCES snapshots (snapshot_id), `cus_id` int)
;
    
INSERT INTO participants
    (`participant_id`, `snapshot_id`, `cus_id`)
VALUES
    (1, 1, 1),
    (2, 1, 3),
    (3, 2, 1),
    (4, 2, 2),
    (5, 2, 3),
    (6, 3, 1),
    (7, 3, 4)
;

我的 SQL 语句:

SELECT s.snapshot_id, 
       hr.name, 
       c1.driver_id AS owner_driver_id,
       md.max_date AS date_added,
       GROUP_CONCAT(c2.driver_id) AS participants_driver_ids 
FROM snapshots s
JOIN (
  SELECT hr.hroom_id, MAX(date_added) AS max_date
  FROM hotel_rooms hr
  JOIN snapshots s ON s.hroom_id = hr.hroom_id
  JOIN participants p ON p.snapshot_id = s.snapshot_id
  JOIN customers c ON c.cus_id = p.cus_id
  WHERE c.cus_id = 1
  GROUP BY hr.hroom_id, hr.name
) md ON md.hroom_id = s.hroom_id AND md.max_date = s.date_added
JOIN hotel_rooms hr ON hr.hroom_id = s.hroom_id
JOIN customers c1 ON c1.cus_id = hr.cus_id
JOIN participants p ON p.snapshot_id = s.snapshot_id
JOIN customers c2 ON c2.cus_id = p.cus_id
GROUP BY s.snapshot_id, hr.name, c1.driver_id, md.max_date
;

表和语句的SQL代码: http : //www.sqlfiddle.com/#!9/6844de/1

期望的输出: 在此处输入图片说明

参与者表的内容基本上是:

  • snapshot_id=1 bobsamsmall room
  • snapshot_id=2 , bob , jamessamsmall room
  • snapshot_id=3bobbillybig room

执行计划: 在此处输入图片说明

但是查询很慢。 我不明白我需要索引什么才能使这个查询更快,因为它们基本上都是连接语句。

对日期时间值使用DATETIME ,而不是VARCHAR

请提供解释EXPLAIN SELECT...

对子查询进行试验——这将有助于确定是子查询还是其他查询缓慢。

snapshot需要一个复合索引INDEX(hroom, date_added)与该顺序的列。

该查询选择在同一天制作的所有快照,客户 #1 拥有同一酒店房间的最后一个快照。

我可能会将子查询写为

SELECT hroom_id, MAX(date_added) AS max_date
FROM snapshots s
WHERE snapshot_id IN (SELECT snapshot_id FROM participants WHERE cus_id = 1)
GROUP BY hroom_id

这使意图变得清晰,我删除了此评估不需要的两个表。

此子查询的索引:

create index idx1 on participants (cus_id, snapshot_id);
create index idx2 on snapshots (snapshot_id, hroom_id, date_added);

主查询的索引:

create index idx3 on snapshots (hroom_id, date_added, snapshot_id);
create index idx4 on hotel_rooms (hroom_id, name);
create index idx5 on customers (cus_id, driver_id);
create index idx6 on participants (snapshot_id, cus_id);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM