有没有更高效的MySql查询

Is there a better MySql query that's more efficient

我在网络搜索的帮助下建立了一个查询,但是对于我拥有的大型数据集来说效率不高。我在 10 天前设置了查询 运行,但还没有完成。我也不知道它实际上走了多远。我相当确定 ORDER BY 部分不是必需的,我不知道它向流程中添加了多少额外内容。

INSERT INTO search_table (TEXT_ID, UPRN, SOURCE_ID) 

SELECT t.TEXT_ID, UPRN, s.SOURCE_ID FROM origin_table stc 

INNER JOIN text_source t ON stc.INDEX_TEXT = t.SOURCE_TEXT 
INNER JOIN index_source s ON stc.SOURCE_COL = s.SOURCE_COL 

GROUP BY t.TEXT_ID, s.SOURCE_ID 
ORDER BY t.TEXT_ID, s.SOURCE_ID

我 运行 一个具有以下结果的解释查询:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE s ALL (NULL) (NULL) (NULL) (NULL) 6 Using temporary; Using filesort
1 SIMPLE t ALL (NULL) (NULL) (NULL) (NULL) 2627372 Using join buffer (flat, BNL join)"
1 SIMPLE stc ALL (NULL) (NULL) (NULL) (NULL) 39603700 Using where; Using join buffer (incremental, BNL join)

感谢任何有关优化此查询的帮助或建议。我非常愿意了解更多关于正在发生的事情以及我如何改进它。

编辑:有人问我查询的实际数据和目的。

我需要一种方法来快速查找主数据集中使用的关键字。关键字及其位置已确定。相同的关键字出现了很多很多次,它们可能会出现在主数据集中 6 列中的任意 1 列中。主数据集仅包含一个索引,即主键。我遇到的另一个问题是每个数据库的大小限制为 1Gb。我可以有 100 个数据库,每个数据库最多 1Gb,但不能有 1 个 100Gb 的数据库。

我的目标基本上是在自己的数据库中创建一个索引,可以在需要时进行查询,提供指向实际主记录的指针(可能还有它以后可能位于的数据库。)或者,假设我将主数据库拆分为 <1Gb 块,我将不得不对大约 30 个不同的数据库执行全文查询。

数据明智:

text_source SOURCE_TEXT 基本上是一组可在主数据集中找到的关键字。大约有 250 万个关键字。

index_source SOURCE_COL 是主数据集中包含的 6 列的列表。因此只有 6 行。

origin_table是一个table,由4列组成,一个PrimaryKey,SEARCH_TEXT是关键字,SOURCE_COL标识关键字的来源,以及UPRN 是最初找到数据的唯一主键。 SEARCH_TEXT 和 SOURCE_COL 都是文本字段。有将近 4000 万行,每行指定关键字的发现位置。

目的地search_table基本上就是上面的原点table删除大量重复的数据并用适当的键替换它

CREATE TABLE `origin_table` (
  `PrimaryKey` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `SEARCH_TEXT` text DEFAULT NULL,
  `UPRN` bigint(20) unsigned DEFAULT NULL,
  `SOURCE_COL` tinytext DEFAULT NULL,
  PRIMARY KEY (`PrimaryKey`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=39845281 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC

CREATE TABLE `search_table` (
  `PrimaryKey` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `INDEX_TEXT` int(10) unsigned DEFAULT NULL,
  `UPRN` bigint(20) unsigned DEFAULT NULL,
  `SOURCE_COL` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`PrimaryKey`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3

CREATE TABLE `index_source` (
  `SOURCE_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `SOURCE_COL` tinytext DEFAULT NULL,
  PRIMARY KEY (`SOURCE_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb3

CREATE TABLE `text_source` (
  `TEXT_ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `INDEX_TEXT` tinytext DEFAULT NULL,
  PRIMARY KEY (`TEXT_ID`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2686936 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC

'Never'使用TINYTEXT,它在功能上等同于VARCHAR(255),但有一些缺点。

SOURCE_COLINDEX_TEXT 有时声明为 INT UNSIGNED,有时声明为 TINYTEXT -- 这种不一致可能会导致意外。很可能它导致了这里糟糕的表现。

GROUP BY 在技术上是不正确的。 (cf ONLY_FULL_GROUP_BY) 因为 UPRN.

并将 innodb_buffer_pool_size 从微小的 259K 更改为 16G。