我有三个表,我想以并行形式从这三个表中选择数据以提高性能。
我正在运行这样的查询。
SELECT * FROM table1
UNION ALL
SELECT * FROM table2
UNION ALL
SELECT * FROM table3
我想问一下,这些查询是并行运行还是按顺序运行?
我可以做些什么来提高这个查询的性能?我可以为每个查询创建一个线程吗?
如果我使用单个连接为此查询创建三个线程,它是否并行工作?或者我需要为每个查询创建三个连接以并行运行?
我读了一些关于这个的文章,我发现它取决于处理器内核。如果有多个内核,它会自动以并行形式运行,如果它是单个处理器,则它必须一个接一个地运行。
我在我的电脑 Core i5 中测试它。我认为核心 i5 至少有两个物理处理器,但它似乎不是以并行形式运行的。
当我使用解释表单两个表运行查询时发现了这一点
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
------------------------------------------------------------------------------------------------------------------------------------------------------
1 PRIMARY table1 NULL ALL NULL NULL NULL NULL 122882 100.00 NULL
2 UNION table2 NULL ALL NULL NULL NULL NULL 122882 100.00 NULL
NULL UNION RESULT <union1,2> NULL ALL NULL NULL NULL NULL NULL NULL Using temporary
实际上,我想在 Google Cloud SQL 上工作是它是否支持以并行形式运行 UNION 查询。
2017 年 10 月 20 日更新
表 1、表 2 和表 3
id int(11) Primary Key
title varchar(100)
description varchar(250)
pic varchar(100)
tag_id int(11)
list_id int(11)
video_src varchar(100)
每个表包含多122882
行。这是目前的位置,但它正在快速增长并达到数百万。我不想在未来面对任何问题。
它不准确,但它列出了类似的内容。
不同表中Partitions相同列的原因是我想根据特定区域保存数据。如果我知道用户区域,我认为从表中获取数据会更快。但有时我需要从多个区域获取数据,例如从 3 个表中获取数据。实际上不是只有 3 个表,而是很多表 PARTITION by country_province_city_tablename
。但在示例中假设只有 3 个表。
查询
当我需要从特定区域获取数据时。
SELECT * FROM `table1` WHERE id = 7
当我需要从多个区域获取数据时。
SELECT * FROM `table1` WHERE id IN(1,5,7,3)
UNION ALL
SELECT * FROM `table2` WHERE id IN(1,6,3,8,2)
UNION ALL
SELECT * FROM `table3` WHERE id IN(6,54,1,5,7)
如您所见WHERE
,子句仅适用于PRIMARY KEY
默认索引的内容。这使得搜索一行变得容易。
您认为PARTITION BY REGION好还是不好?
以及如何以并行形式运行这些查询以提高性能?
table1、table2 和 table3 只是占位符 用确切的名称替换它们
table1 --> PK_PNJ_PTK_Posts
table2 --> PK_ISB_RWP_Posts
table3 --> PK_PNJ_KSR_Posts
表格中的行
//table1 or PK_PNJ_PTK_Posts
id title description tag_id list_id video_src
----------------------------------------------------------------------
1 Title1 desc1 37 13 path/to/file1
2 Title2 desc2 43 34 path/to/file2
3 Title3 desc3 433 4 path/to/file3
4 Title4 desc4 53 36 path/to/file4
5 Title5 desc5 43 31 path/to/file5
6 Title6 desc6 73 54 path/to/file6
7 Title7 desc7 3 9 path/to/file7
8 Title8 desc8 53 56 path/to/file8
9 Title9 desc9 13 32 path/to/file9
.. .... ... .. .. ....
.. .... ... .. .. ....
//table2 or PK_ISB_RWP_Posts
id title description tag_id list_id video_src
----------------------------------------------------------------------
1 Title1 desc1 37 13 path/to/file1
2 Title2 desc2 43 34 path/to/file2
3 Title3 desc3 433 4 path/to/file3
4 Title4 desc4 53 36 path/to/file4
5 Title5 desc5 43 31 path/to/file5
6 Title6 desc6 73 54 path/to/file6
7 Title7 desc7 3 9 path/to/file7
8 Title8 desc8 53 56 path/to/file8
9 Title9 desc9 13 32 path/to/file9
.. .... ... .. .. ....
.. .... ... .. .. ....
//table3 or PK_PNJ_KSR_Posts
id title description tag_id list_id video_src
----------------------------------------------------------------------
1 Title1 desc1 37 13 path/to/file1
2 Title2 desc2 43 34 path/to/file2
3 Title3 desc3 433 4 path/to/file3
4 Title4 desc4 53 36 path/to/file4
5 Title5 desc5 43 31 path/to/file5
6 Title6 desc6 73 54 path/to/file6
7 Title7 desc7 3 9 path/to/file7
8 Title8 desc8 53 56 path/to/file8
9 Title9 desc9 13 32 path/to/file9
.. .... ... .. .. ....
.. .... ... .. .. ....
MySQL 不使用多个 CPU 进行任何查询,甚至不使用
UNION
orPARTITION
(可能的候选者)。多个连接(不仅仅是多个线程)可以并行做事。但是建立连接和收集 3 组数据的开销可能会更糟。
更糟糕的是,
UNION
总是创建一个 tmp 表来收集单独的SELECTs
数据。(这种低效率在 8.0 中被许多人(不是全部)消除了UNIONs
。)UNION ALL
比UNION DISTINCT
or更有效UNION
,因为不需要重复数据删除。您的 3 个表有非常相似的列?如果它们相同,我不得不问你为什么它们是 3 个不同的表而不是一个表。
您可能遇到的一个低效率问题是
*
——如果其中包括您不需要获取的大列TEXT
或列,那么性能可能会受到严重阻碍。BLOB
(这是由于 InnoDB 存储大量数据的方式。)并行性并不总是有益的——例如,如果 I/O 争用过多,则可能没有任何好处。
您将如何处理结果集?您期望有多少行。给我们更多细节;可能有一些开箱即用的解决方案可以简单地避免此查询。
单表;'id=7' 可以出现在多个区域
首先,我需要了解
id
. 由于我7
在多个表中看到,我假设它来自 table1/2/3 以外的某个地方?并且7
可能存在于任意数量的“区域”中?单表;'id=7' 只能出现在一个区域
PARTITION BY LIST(region) 和 'id=7' 可以出现在多个区域
警告:当一个表超过大约 50 时,性能会受到影响
PARTITIONs
。(将在 8.0 中修复。)底线(假设多个 7):单个未分区表的性能与分区表大致相同。
PS:在所有情况下(到目前为止),都比(我相信)
UNION ALL
快。OR
最好的
最好的解决方案(虽然不是很实用)是将记录重新编号,使其在所有区域中都是唯一的。然后有一个表,查询只涉及
id
: