【问题标题】:Optimize speed of Mysql JOIN query优化Mysql JOIN查询速度
【发布时间】:2019-08-30 12:16:15
【问题描述】:

我有 2 个表,名为 T1 由 160 万行组成,T2 由 460 万行组成,具有一对多关系。

T1 的 CREATE STMT 是:

CREATE TABLE `T1` (
  `field_1` text,
  `field_2` text,
  `field_3` decimal(10,6) DEFAULT NULL,
  `field_4` decimal(10,6) DEFAULT NULL,
  `field_4` decimal(10,6) DEFAULT NULL,
  `field_5` text,
  `field_6` text,
  `field_7` text,
  `field_8` double DEFAULT NULL,
  `field_9` text,
  `field_10` text,
  `field_11` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

T2 的 CREATE STMT 是:

CREATE TABLE `T2` (
  `field_1` int(11) DEFAULT NULL,
  `field_2` text,
  `field_3` text,
  `field_4` text,
  `field_5` text,
  `field_6` text,
  `field_7` text,
  `field_8` text,
  `field_9` text,
  `field_10` text,
  `field_11` text,
  `field_12` text,
  `field_13` text
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我暂时没有设置任何类型的索引或任何特定的限制条件,但T1.field_1 应该是我理想的键并且可以与T2.field_2 字段连接。

如果我决定像这样进行 JOIN:

SELECT * FROM T1
JOIN T2
ON T1.field_1=T2.field_2
WHERE T1.=2130100;

基准真的很高。 这是解释:

所以我只是想了解可能有哪些改进:

  • 添加一些索引
  • 更改输入字段的类型?
  • 可以添加主键吗?

【问题讨论】:

  • 按列类型比较表 TEXT 是个坏主意。
  • 历史上 VARCHAR 比 TEXT 快。
  • 是的 - 全部。
  • @JoopEggen - 在某些情况下,varchar 和 text 具有相同的性能;在某些情况下,TEXT 会明显变慢(涉及额外的磁盘命中)。

标签: mysql database join indexing query-performance


【解决方案1】:

在你错过列名的情况下,我假设这些列被命名为 your_col

从 mysql 5.0.3 开始,varchar 可以达到 65,535,因此您可以在可能的情况下尝试使用 varchar 而不是文本

对于索引,索引的大小有限制,最大密钥长度为 767 字节(假设每个 utf8 字符 3 个字节。所以大约 250 个 utf8 字符)

索引的候选列必须遵守这些限制 如果这是可能的,那么你可以 在

上添加索引

table t2 列 fiedl_2

然后

table t1 a composite index on  column (Your_col, field_1) 

这些是where和ON子句中涉及的列

  SELECT * FROM T1
  JOIN T2
  ON T1.field_1=T2.field_2
  WHERE T1.Your_col=2130100;

【讨论】:

  • 可以,在实用的地方切换到VARCHAR,但是不行,不要盲目使用VARCHAR(65535);这将和TEXT 一样糟糕。选择合理的最大尺寸。
【解决方案2】:

由于您使用的是latin1,请将t1.field_1t2.field_2 切换为不超过767 的VARCHAR。使用不太可能超过的最短值。对所有其他 TEXT 列执行同样的操作。 (如果您需要 >767,请坚持使用TEXT。)

然后添加两个索引:

T1:  INDEX(??) -- whatever column you are using in the `WHERE`
T2:  INDEX(field_2)

如果 T1 中的列是 INT,那么 2130100 是可以的。但如果是TEXT(或即将成为VARCHAR(..),则引用它:"2130100"。应该防止对T1 进行令人惊讶且不必要的表扫描。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    相关资源
    最近更新 更多