Optimize SQL that uses between clause

前端 未结 19 2124
故里飘歌
故里飘歌 2021-01-11 18:03

Consider the following 2 tables:

Table A:
id
event_time

Table B
id
start_time
end_time

Every record in table A is mapped to exactly 1 reco

19条回答
  •  一个人的身影
    2021-01-11 18:30

    MySQL doesn't let you to use INDEX ORDER BY WITH RANGE in derived queries.

    That's why you'll need to create a user defined function.

    Note that if your ranges do overlap, the query will only select one (which started last).

    CREATE UNIQUE INDEX ux_b_start ON b (start_date);
    
    CREATE FUNCTION `fn_get_last_b`(event_date TIMESTAMP) RETURNS int(11)
    BEGIN
      DECLARE id INT;
      SELECT b.id
      INTO id
      FROM b
      FORCE INDEX (ux_b_start)
      WHERE b.start_time <= event_date
      ORDER BY
        b.start_time DESC
      LIMIT 1;
      RETURN id;
    END;
    
    SELECT COUNT(*) FROM a;
    
    1000
    
    
    SELECT COUNT(*) FROM b;
    
    200000
    
    SELECT *
    FROM (
      SELECT fn_get_last_b(a.event_time) AS bid,
             a.*
      FROM a
    ) ao, b FORCE INDEX (PRIMARY)
    WHERE b.id = ao.bid
      AND b.end_time >= ao.event_time
    
    1000 rows fetched in 0,0143s (0,1279s)
    

提交回复
热议问题