有没有更高效的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_COL
和 INDEX_TEXT
有时声明为 INT UNSIGNED
,有时声明为 TINYTEXT
-- 这种不一致可能会导致意外。很可能它导致了这里糟糕的表现。
GROUP BY
在技术上是不正确的。 (cf ONLY_FULL_GROUP_BY
) 因为 UPRN
.
并将 innodb_buffer_pool_size
从微小的 259K 更改为 16G。
我在网络搜索的帮助下建立了一个查询,但是对于我拥有的大型数据集来说效率不高。我在 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_COL
和 INDEX_TEXT
有时声明为 INT UNSIGNED
,有时声明为 TINYTEXT
-- 这种不一致可能会导致意外。很可能它导致了这里糟糕的表现。
GROUP BY
在技术上是不正确的。 (cf ONLY_FULL_GROUP_BY
) 因为 UPRN
.
并将 innodb_buffer_pool_size
从微小的 259K 更改为 16G。