gpt4 book ai didi

Mysql、handlersocket 和分区?

转载 作者:可可西里 更新时间:2023-11-01 06:32:29 25 4
gpt4 key购买 nike

handlersocket 插件是否知道表上可能的分区?我没有在相关文档中找到提及,我什至不知道分区是否对处理程序套接字透明,或者它是 sql 优化器所做的事情。

最佳答案

简答:

HandlerSocket 对分区表工作良好(意味着支持所有操作),但它不知道任何分区。不尝试分区修剪,因此当 handlersocket 与分区表一起使用时会产生性能开销。

长答案:

MySQL 中的分区是在不同级别实现的:解析器、通用处理程序、查询优化器。通用处理程序 (ha_partition) 为 native 不支持它的引擎提供分区(除 NDB 之外的所有引擎)。这个处理程序实现了一种责任链模式:它将自己插入服务器和底层引擎的普通处理程序之间(每个分区一个)。

执行查询时,ha_partition 处理程序将操作转发给与每个分区对应的所有底层处理程序。这就是为什么您可以为 InnoDB、MyISAM 等提供相同的分区支持......

分区修剪(即过滤掉分区上无用的查找/扫描)在查询优化器中实现,而不是在 ha_partition 处理程序中实现。所以基本上当通过 ha_partition 完成查找时,如果优化器没有限制分区列表,查找将在所有分区上完成,然后使用合并算法并行读取 n 个游标。

以下presentation由 Mattias Jonsson 和 Mikael Ronström (Oracle) 撰写,对于理解如何在 MySQL 中实现分区非常有用。

现在 HandlerSocket 插件直接基于通用处理程序。 HandlerSocket 级别没有分区知识。当对分区表应用 HandlerSocket 查询时,将以透明方式使用 ha_partition 处理程序。

好消息是 HandlerSocket 可以很好地处理分区表,无需额外费用。坏消息是它无法从分区修剪中获益,因为这仅在 SQL 查询优化器中实现。

这是一个证明它的例子(针对 Percona Server 5.5 测试)。我们将使用 2 个表:mytable_np 未分区,mytable 已分区。

create table mytable_np ( id int, x varchar(100), primary key(id), key(x) )
engine=InnoDB ;

insert into mytable_np values ( 1, 'A' );
insert into mytable_np values ( 11, 'B' );
insert into mytable_np values ( 21, 'C' );
insert into mytable_np values ( 31, 'D' );
insert into mytable_np values ( 41, 'E' );
insert into mytable_np values ( 51, 'F' );
commit;

create table mytable ( id int, x varchar(100), primary key(id), key(x) )
engine=InnoDB
partition by range (id) (
partition p0 values less than (10),
partition p1 values less than (20),
partition p2 values less than (30),
partition p3 values less than (40),
partition p4 values less than (50),
partition pend values less than (1000)
);

insert into mytable values ( 1, 'A' );
insert into mytable values ( 11, 'B' );
insert into mytable values ( 21, 'C' );
insert into mytable values ( 31, 'D' );
insert into mytable values ( 41, 'E' );
insert into mytable values ( 51, 'F' );
commit;

可以执行以下查询来执行简单的主键访问:

select * from mytable where id = 51 ;

select * from mytable_np where id = 51 ;

以下 netcat/telnet 脚本可用于使用 HandlerSocket 进行查询(注意 TAB 字符):

P       0       test    mytable PRIMARY id,x                                                                                                                                                                                                 
0 = 1 51

P 0 test mytable_np PRIMARY id,x
0 = 1 51

为了评估查找次数,可以在每次查询执行前后执行以下查询以计算处理程序键访问的次数:

show global status like 'Handler_read_key' ;

如果我们测量在四种情况下完成的处理程序 key 访问次数,我们得到:

SQL query against non partitioned table:      2
SQL query against partitioned table: 2
HandlerSocket against non partitioned table: 2
HandlerSocket against partitioned table: 7

在前三种情况下,我们有一个查找来查找行,加上一个额外的键访问来检查这是要读取的最后一行。在最后一种情况下,我们对每个非空分区进行一次查找。其中有 6 个。 key 只会在其中一个中找到,并且会进行额外的访问以检查是否只有一个匹配行。所以结果是 7。

这个例子证明,即使在最简单的情况下(主键访问),HandlerSocket 也无法修剪分区。当对分区使用 HandlerSocket 时,应该总是会出现性能损失。分区越多,开销越高(线性)。

关于Mysql、handlersocket 和分区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8477515/

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