2

问题:查询慢。

  • table1大约有 5 000 行
  • table2大约有 50 000 行
  • 时间戳格式是int(11)
  • MySQL - 20 秒(带索引)
  • PostgreSQL - 0,04 秒(带索引)

    SELECT * 
    FROM table1
      LEFT JOIN table2 
        ON table2_timestamp BETWEEN table1_timestamp - 500 
                                AND table1_timestamp + 500 ;
    

任何人都可以帮我优化这个 MySQL 查询吗?

解释:

1   SIMPLE  a   index       a   9       2   Using index
1   SIMPLE  b   index   b   b   9       5   Using index

表:

CREATE TABLE `a` (
  `id`  int(11) NOT NULL AUTO_INCREMENT ,
  `table1_timestamp`  bigint(20) NULL DEFAULT NULL ,
  PRIMARY KEY (`id`),
  INDEX `a` (`table1_timestamp`) USING BTREE 
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=3
ROW_FORMAT=COMPACT
;

CREATE TABLE `b` (
  `id`  int(11) NOT NULL AUTO_INCREMENT ,
  `table2_timestamp`  bigint(20) NULL DEFAULT NULL ,
  PRIMARY KEY (`id`),
  INDEX `a` (`table2_timestamp`) USING BTREE 
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=3
ROW_FORMAT=COMPACT
;
4

1 回答 1

1

A couple of points spring to mind but both feel like long-shots. Realistically it looks as though there shouldn't be much you can do to your query assuming your example is an accurate representation.

1 : You are using BIGINT which has a maximum value of 9x10^18 (SIGNED). INT has a max value of 4x10^9 (UNSIGNED), compared to days timestamp which is around 1.4x10^9 (all values approximate) and so consider changing the data type of that column in both tables from BIGINT to INT UNSIGNED or DATETIME

2 : The ROW_FORMAT is COMPACT which may cause issues with BTREE indexes (source). You are dealing with INT data types and so a ROW_FORMAT of FIXED would suffice so try changing to ROW_FORMAT=FIXED on both tables

3 : If always expecting rows to be returned from table2 for table1 rows then INNER JOIN would be more efficient than LEFT JOIN

于 2013-06-11T17:36:12.430 回答