gpt4 book ai didi

mysql - 为什么并行执行查询时MySQL的性能会下降?

转载 作者:行者123 更新时间:2023-12-05 00:51:39 26 4
gpt4 key购买 nike

问题:为什么并行执行连接几乎空表的查询的MySQL性能下降?

以下是我所面临问题的更详细说明。我在MySQL中有两个表

CREATE TABLE first (
num int(10) NOT NULL,
UNIQUE KEY key_num (num)
) ENGINE=InnoDB

CREATE TABLE second (
num int(10) NOT NULL,
num2 int(10) NOT NULL,
UNIQUE KEY key_num (num, num2)
) ENGINE=InnoDB


第一个包含大约一千条记录。第二个为空或包含很少的记录。它还包含与该问题有某种联系的双索引:单索引的问题消失了。现在,我试图并行地对这些表进行很多相同的查询。每个查询如下所示:

SELECT first.num
FROM first
LEFT JOIN second AS second_1 ON second_1.num = -1 # non-existent key
LEFT JOIN second AS second_2 ON second_2.num = -2 # non-existent key
LEFT JOIN second AS second_3 ON second_3.num = -3 # non-existent key
LEFT JOIN second AS second_4 ON second_4.num = -4 # non-existent key
LEFT JOIN second AS second_5 ON second_5.num = -5 # non-existent key
LEFT JOIN second AS second_6 ON second_6.num = -6 # non-existent key
WHERE second_1.num IS NULL
AND second_2.num IS NULL
AND second_3.num IS NULL
AND second_4.num IS NULL
AND second_5.num IS NULL
AND second_6.num IS NULL


我遇到的问题是,与在8核计算机上的性能几乎没有线性提高相比,我实际上有所下降。即有一个进程,我每秒典型的请求数约为200。有两个进程而不是预期的每秒增加300至400个查询,实际上我下降到150个。对于10个进程,我只有70个查询每秒。我用于测试的Perl代码如下所示:

#!/usr/bin/perl

use strict;
use warnings;

use DBI;
use Parallel::Benchmark;
use SQL::Abstract;
use SQL::Abstract::Plugin::InsertMulti;

my $children_dbh;

foreach my $second_table_row_count (0, 1, 1000) {
print '#' x 80, "\nsecond_table_row_count = $second_table_row_count\n";
create_and_fill_tables(1000, $second_table_row_count);
foreach my $concurrency (1, 2, 3, 4, 6, 8, 10, 20) {
my $bm = Parallel::Benchmark->new(
'benchmark' => sub {
_run_sql();
return 1;
},
'concurrency' => $concurrency,
'time' => 3,
);
my $result = $bm->run();
}
}

sub create_and_fill_tables {
my ($first_table_row_count, $second_table_row_count) = @_;
my $dbh = dbi_connect();
{
$dbh->do(q{DROP TABLE IF EXISTS first});
$dbh->do(q{
CREATE TABLE first (
num int(10) NOT NULL,
UNIQUE KEY key_num (num)
) ENGINE=InnoDB
});
if ($first_table_row_count) {
my ($stmt, @bind) = SQL::Abstract->new()->insert_multi(
'first',
['num'],
[map {[$_]} 1 .. $first_table_row_count],
);
$dbh->do($stmt, undef, @bind);
}
}
{
$dbh->do(q{DROP TABLE IF EXISTS second});
$dbh->do(q{
CREATE TABLE second (
num int(10) NOT NULL,
num2 int(10) NOT NULL,
UNIQUE KEY key_num (num, num2)
) ENGINE=InnoDB
});
if ($second_table_row_count) {
my ($stmt, @bind) = SQL::Abstract->new()->insert_multi(
'second',
['num'],
[map {[$_]} 1 .. $second_table_row_count],
);
$dbh->do($stmt, undef, @bind);
}
}
}

sub _run_sql {
$children_dbh ||= dbi_connect();
$children_dbh->selectall_arrayref(q{
SELECT first.num
FROM first
LEFT JOIN second AS second_1 ON second_1.num = -1
LEFT JOIN second AS second_2 ON second_2.num = -2
LEFT JOIN second AS second_3 ON second_3.num = -3
LEFT JOIN second AS second_4 ON second_4.num = -4
LEFT JOIN second AS second_5 ON second_5.num = -5
LEFT JOIN second AS second_6 ON second_6.num = -6
WHERE second_1.num IS NULL
AND second_2.num IS NULL
AND second_3.num IS NULL
AND second_4.num IS NULL
AND second_5.num IS NULL
AND second_6.num IS NULL
});
}

sub dbi_connect {
return DBI->connect(
'dbi:mysql:'
. 'database=tmp'
. ';host=localhost'
. ';port=3306',
'root',
'',
);
}


对于这样的比较查询,在提高性能的同时执行:

SELECT first.num
FROM first
LEFT JOIN second AS second_1 ON second_1.num = 1 # existent key
LEFT JOIN second AS second_2 ON second_2.num = 2 # existent key
LEFT JOIN second AS second_3 ON second_3.num = 3 # existent key
LEFT JOIN second AS second_4 ON second_4.num = 4 # existent key
LEFT JOIN second AS second_5 ON second_5.num = 5 # existent key
LEFT JOIN second AS second_6 ON second_6.num = 6 # existent key
WHERE second_1.num IS NOT NULL
AND second_2.num IS NOT NULL
AND second_3.num IS NOT NULL
AND second_4.num IS NOT NULL
AND second_5.num IS NOT NULL
AND second_6.num IS NOT NULL


测试结果,cpu和磁盘使用情况的测量结果如下:

*表`first`有1000行
* table`second`有6行:[[1,1],[2,2],.. [6,6]`

查询:
选择first.num
从第一
LEFT JOIN second AS second_1 ON second_1.num = -1#不存在的密钥
LEFT JOIN second AS second_2 ON second_2.num = -2#不存在的密钥
LEFT JOIN second AS second_3 ON second_3.num = -3#不存在的密钥
LEFT JOIN second AS second_4 ON second_4.num = -4#不存在的密钥
LEFT JOIN second AS second_5 ON second_5.num = -5#不存在的密钥
LEFT JOIN second AS second_6 ON second_6.num = -6#不存在的密钥
WHERE second_1.num是NULL
AND second_2.num为NULL
AND second_3.num为NULL
AND second_4.num为NULL
AND second_5.num为NULL
AND second_6.num为NULL

结果:
并发数:1,速度:162.910 /秒
并发:2,速度:137.818 /秒
并发:3,速度:130.728 /秒
并发:4,速度:107.387 /秒
并发:6,速度:90.513 /秒
并发:8,速度:80.445 /秒
并发:10,速度:80.381 /秒
并发:20,速度:84.069 /秒

在6个进程中运行查询的最后60分钟之后的系统使用情况:
$ iostat -cdkx 60

avg-cpu:%user%nice%system%iowait%steal%idle
74.82 0.00 0.08 0.00 0.08 25.02

设备:rrqm / s wrqm / s r / s w / s rkB / s wkB / s avgrq-sz avgqu-sz等待svctm%util
sda1 0.00 0.00 0.00 0.12 0.00 0.80 13.71 0.00 1.43 1.43 0.02
sdf10 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf4 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 30.00 15.00 0.05
sdm 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf8 0.00 0.00 0.00 0.37 0.00 1.24 6.77 0.00 5.00 3.18 0.12
sdf6 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf9 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 0.00 0.00 0.00
sdf 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf3 0.00 0.00 0.00 0.08 0.00 1.33 32.00 0.00 4.00 4.00 0.03
sdf2 0.00 0.00 0.00 0.17 0.00 1.37 16.50 0.00 3.00 3.00 0.05
sdf15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf14 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf1 0.00 0.00 0.00 0.05 0.00 0.40 16.00 0.00 0.00 0.00 0.00
sdf13 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf5 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 50.00 25.00 0.08
sdm2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdm1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf12 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf11 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf7 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
md0 0.00 0.00 0.00 0.00 0.97 0.00 13.95 28.86 0.00 0.00 0.00 0.00 0.00

################################################ #############################

查询:
选择first.num
从第一
左联接second AS AS second_1 ON second_1.num = 1#存在键
LEFT JOIN second AS second_2 ON second_2.num = 2#存在键
LEFT JOIN second AS second_3 ON second_3.num = 3#存在的键
LEFT JOIN second AS second_4 ON second_4.num = 4#存在键
LEFT JOIN second AS second_5 ON second_5.num = 5#存在键
LEFT JOIN second AS second_6 ON second_6.num = 6#存在键
其中second_1.num不为空
AND second_2.num不为空
AND second_3.num不为空
AND second_4.num不为空
AND second_5.num不为空
AND second_6.num不为空

结果:
并发:1,速度:875.973 /秒
并发:2,速度:944.986 /秒
并发:3,速度:1256.072 /秒
并发:4,速度:1401.657 /秒
并发:6,速度:1354.351 /秒
并发:8,速度:1110.100 /秒
并发:10,速度:1145.251 /秒
并发:20,速度:1142.514 /秒

在6个进程中运行查询的最后60分钟之后的系统使用情况:
$ iostat -cdkx 60

avg-cpu:%user%nice%system%iowait%steal%idle
74.40 0.00 0.53 0.00 0.06 25.01

设备:rrqm / s wrqm / s r / s w / s rkB / s wkB / s avgrq-sz avgqu-sz等待svctm%util
sda1 0.00 0.00 0.00 0.00 0.02 0.00 0.13 16.00 0.00 0.00 0.00 0.00
sdf10 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf4 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdm 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf8 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf6 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 0.00 0.00 0.00
sdf9 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdf 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf3 0.00 0.00 0.00 0.13 0.00 2.67 40.00 0.00 3.75 2.50 0.03
sdf2 0.00 0.00 0.00 0.23 0.00 2.72 23.29 0.00 2.14 1.43 0.03
sdf15 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf14 0.00 0.00 0.00 0.98 0.00 0.54 1.10 0.00 2.71 2.71 0.27
sdf1 0.00 0.00 0.00 0.08 0.00 1.47 35.20 0.00 8.00 6.00 0.05
sdf13 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf5 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
sdm2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdm1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdf11 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 0.00 0.00 0.00
sdf7 0.00 0.00 0.00 0.03 0.00 1.07 64.00 0.00 10.00 5.00 0.02
md0 0.00 0.00 0.00 1.70 0.00 15.92 18.74 0.00 0.00 0.00 0.00

################################################ #############################

并且该服务器具有大量可用内存。顶部示例:
顶部-19:02:59最多4:23,有4个用户,平均负载:4.43、3.03、2.01
任务:总共218次,正在跑步1次,睡眠217次,停止0次,丧尸0次
Cpu(s):72.8%us,0.7%sy,0.0%ni,26.3%id,0.0%wa,0.0%hi,0.0%si,0.1%st
内存:总计71701416k,已使用22183980k,免费49517436k,缓冲284k
交换:总0k,已使用0k,免费0k,已缓存1282768k

PID用户PR NI VIRT RES SHR S%CPU%MEM TIME +命令
2506 MySQL 20 0 51.7g 17g 5920 S 590 25.8 213:15.12 mysqld
9348 topadver 20 0 72256 11m 1428 S 2 0.0 0:01.45 perl
9349 topadver 20 0 72256 11m 1428 S 2 0.0 0:01.44 perl
9350 topadver 20 0 72256 11m 1428 S 2 0.0 0:01.45 perl
9351 topadver 20 0 72256 11m 1428 S 1 0.0 0:01.44 perl
9352 topadver 20 0 72256 11m 1428 S 1 0.0 0:01.44 perl
9353 topadver 20 0 72256 11m 1428 S 1 0.0 0:01.44 perl
9346 topadver 20 0 19340 1504 1064 R 0 0.0 0:01.89返回页首


有谁知道为什么不存在的键查询性能会下降?

最佳答案

写得很好的问题,表明了一些研究。

出于好奇,我尝试使用MySQL 5.6来查看那里的工具对这些查询的评价。

首先,请注意查询是不同的:


将存在/不存在的值从“ 1”更改为“ -1”
关键案例是一回事
将“ second_1.num不为空”更改为
WHERE子句中的“ second_1.num IS NULL”是另一个。


使用EXPLAIN会给出不同的计划:

EXPLAIN SELECT `first`.num
FROM `first`
LEFT JOIN `second` AS second_1 ON second_1.num = -1 # non-existent key
LEFT JOIN `second` AS second_2 ON second_2.num = -2 # non-existent key
LEFT JOIN `second` AS second_3 ON second_3.num = -3 # non-existent key
LEFT JOIN `second` AS second_4 ON second_4.num = -4 # non-existent key
LEFT JOIN `second` AS second_5 ON second_5.num = -5 # non-existent key
LEFT JOIN `second` AS second_6 ON second_6.num = -6 # non-existent key
WHERE second_1.num IS NULL
AND second_2.num IS NULL
AND second_3.num IS NULL
AND second_4.num IS NULL
AND second_5.num IS NULL
AND second_6.num IS NULL
;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE first index NULL key_num 4 NULL 1000 Using index
1 SIMPLE second_1 ref key_num key_num 4 const 1 Using where; Not exists; Using index
1 SIMPLE second_2 ref key_num key_num 4 const 1 Using where; Not exists; Using index
1 SIMPLE second_3 ref key_num key_num 4 const 1 Using where; Not exists; Using index
1 SIMPLE second_4 ref key_num key_num 4 const 1 Using where; Not exists; Using index
1 SIMPLE second_5 ref key_num key_num 4 const 1 Using where; Not exists; Using index
1 SIMPLE second_6 ref key_num key_num 4 const 1 Using where; Not exists; Using index


相对于

EXPLAIN SELECT `first`.num
FROM `first`
LEFT JOIN `second` AS second_1 ON second_1.num = 1 # existent key
LEFT JOIN `second` AS second_2 ON second_2.num = 2 # existent key
LEFT JOIN `second` AS second_3 ON second_3.num = 3 # existent key
LEFT JOIN `second` AS second_4 ON second_4.num = 4 # existent key
LEFT JOIN `second` AS second_5 ON second_5.num = 5 # existent key
LEFT JOIN `second` AS second_6 ON second_6.num = 6 # existent key
WHERE second_1.num IS NOT NULL
AND second_2.num IS NOT NULL
AND second_3.num IS NOT NULL
AND second_4.num IS NOT NULL
AND second_5.num IS NOT NULL
AND second_6.num IS NOT NULL
;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE second_1 ref key_num key_num 4 const 1 Using index
1 SIMPLE second_2 ref key_num key_num 4 const 1 Using index
1 SIMPLE second_3 ref key_num key_num 4 const 1 Using index
1 SIMPLE second_4 ref key_num key_num 4 const 1 Using index
1 SIMPLE second_5 ref key_num key_num 4 const 1 Using index
1 SIMPLE second_6 ref key_num key_num 4 const 1 Using index
1 SIMPLE first index NULL key_num 4 NULL 1000 Using index; Using join buffer (Block Nested Loop)


使用JSON格式,我们可以:

EXPLAIN FORMAT=JSON SELECT `first`.num
FROM `first`
LEFT JOIN `second` AS second_1 ON second_1.num = -1 # non-existent key
LEFT JOIN `second` AS second_2 ON second_2.num = -2 # non-existent key
LEFT JOIN `second` AS second_3 ON second_3.num = -3 # non-existent key
LEFT JOIN `second` AS second_4 ON second_4.num = -4 # non-existent key
LEFT JOIN `second` AS second_5 ON second_5.num = -5 # non-existent key
LEFT JOIN `second` AS second_6 ON second_6.num = -6 # non-existent key
WHERE second_1.num IS NULL
AND second_2.num IS NULL
AND second_3.num IS NULL
AND second_4.num IS NULL
AND second_5.num IS NULL
AND second_6.num IS NULL
;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "first",
"access_type": "index",
"key": "key_num",
"key_length": "4",
"rows": 1000,
"filtered": 100,
"using_index": true
}
},
{
"table": {
"table_name": "second_1",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"not_exists": true,
"using_index": true,
"attached_condition": "<if>(found_match(second_1), isnull(`test`.`second_1`.`num`), true)"
}
},
{
"table": {
"table_name": "second_2",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"not_exists": true,
"using_index": true,
"attached_condition": "<if>(found_match(second_2), isnull(`test`.`second_2`.`num`), true)"
}
},
{
"table": {
"table_name": "second_3",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"not_exists": true,
"using_index": true,
"attached_condition": "<if>(found_match(second_3), isnull(`test`.`second_3`.`num`), true)"
}
},
{
"table": {
"table_name": "second_4",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"not_exists": true,
"using_index": true,
"attached_condition": "<if>(found_match(second_4), isnull(`test`.`second_4`.`num`), true)"
}
},
{
"table": {
"table_name": "second_5",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"not_exists": true,
"using_index": true,
"attached_condition": "<if>(found_match(second_5), isnull(`test`.`second_5`.`num`), true)"
}
},
{
"table": {
"table_name": "second_6",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"not_exists": true,
"using_index": true,
"attached_condition": "<if>(found_match(second_6), isnull(`test`.`second_6`.`num`), true)"
}
}
]
}
}


相对于

EXPLAIN FORMAT=JSON SELECT `first`.num
FROM `first`
LEFT JOIN `second` AS second_1 ON second_1.num = 1 # existent key
LEFT JOIN `second` AS second_2 ON second_2.num = 2 # existent key
LEFT JOIN `second` AS second_3 ON second_3.num = 3 # existent key
LEFT JOIN `second` AS second_4 ON second_4.num = 4 # existent key
LEFT JOIN `second` AS second_5 ON second_5.num = 5 # existent key
LEFT JOIN `second` AS second_6 ON second_6.num = 6 # existent key
WHERE second_1.num IS NOT NULL
AND second_2.num IS NOT NULL
AND second_3.num IS NOT NULL
AND second_4.num IS NOT NULL
AND second_5.num IS NOT NULL
AND second_6.num IS NOT NULL
;
EXPLAIN
{
"query_block": {
"select_id": 1,
"nested_loop": [
{
"table": {
"table_name": "second_1",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"using_index": true
}
},
{
"table": {
"table_name": "second_2",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"using_index": true
}
},
{
"table": {
"table_name": "second_3",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"using_index": true
}
},
{
"table": {
"table_name": "second_4",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"using_index": true
}
},
{
"table": {
"table_name": "second_5",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"using_index": true
}
},
{
"table": {
"table_name": "second_6",
"access_type": "ref",
"possible_keys": [
"key_num"
],
"key": "key_num",
"key_length": "4",
"ref": [
"const"
],
"rows": 1,
"filtered": 100,
"using_index": true
}
},
{
"table": {
"table_name": "first",
"access_type": "index",
"key": "key_num",
"key_length": "4",
"rows": 1000,
"filtered": 100,
"using_index": true,
"using_join_buffer": "Block Nested Loop"
}
}
]
}
}


查看性能模式在运行时提供的表io,我们有:

truncate table performance_schema.objects_summary_global_by_type;
select * from performance_schema.objects_summary_global_by_type
where OBJECT_NAME in ("first", "second");
OBJECT_TYPE OBJECT_SCHEMA OBJECT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
TABLE test first 0 0 0 0 0
TABLE test second 0 0 0 0 0
SELECT `first`.num
FROM `first`
LEFT JOIN `second` AS second_1 ON second_1.num = -1 # non-existent key
LEFT JOIN `second` AS second_2 ON second_2.num = -2 # non-existent key
LEFT JOIN `second` AS second_3 ON second_3.num = -3 # non-existent key
LEFT JOIN `second` AS second_4 ON second_4.num = -4 # non-existent key
LEFT JOIN `second` AS second_5 ON second_5.num = -5 # non-existent key
LEFT JOIN `second` AS second_6 ON second_6.num = -6 # non-existent key
WHERE second_1.num IS NULL
AND second_2.num IS NULL
AND second_3.num IS NULL
AND second_4.num IS NULL
AND second_5.num IS NULL
AND second_6.num IS NULL
;
(...)
select * from performance_schema.objects_summary_global_by_type
where OBJECT_NAME in ("first", "second");
OBJECT_TYPE OBJECT_SCHEMA OBJECT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
TABLE test first 1003 5705014442 1026171 5687889 87356557
TABLE test second 6012 271786533972 537266 45207298 1123939292


相对于:

select * from performance_schema.objects_summary_global_by_type
where OBJECT_NAME in ("first", "second");
OBJECT_TYPE OBJECT_SCHEMA OBJECT_NAME COUNT_STAR SUM_TIMER_WAIT MIN_TIMER_WAIT AVG_TIMER_WAIT MAX_TIMER_WAIT
TABLE test first 1003 5211074603 969338 5195454 61066176
TABLE test second 24 458656783 510085 19110361 66229860


可扩展的查询在表 second中几乎没有表IO。
无法缩放的查询在表 second中执行6K表IO,或者是表 first大小的6倍。

这是因为查询计划不同,又因为查询不同(IS NOT NULL与IS NULL)。

我认为这回答了与性能有关的问题。

请注意,这两个查询在我的测试中都返回了1000行,这可能不是您想要的。
在调整查询以使其更快之前,请确保其按预期工作。

关于mysql - 为什么并行执行查询时MySQL的性能会下降?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11160522/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com