前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Myrocks基本查询源码

Myrocks基本查询源码

原创
作者头像
devsql
发布2019-04-11 17:12:39
1.5K0
发布2019-04-11 17:12:39
举报
文章被收录于专栏:MySQL内核MySQL内核

Myrocks是Percona在MySQL上接入了Rocksdb引擎的产物,接入新引擎的主要修改的地方就是MySQL的handler接口。以下针对常用的几个查询分析Myrocks是如何进行处理的。设有表 t1(a INT, b INT)

a

b

1

1

2

2

3

3

4

4

t2(a INT PRIMARY KEY, b INT, INDEX(b))

a

b

1

1

2

2

3

3

4

4

t3(a INT PRIMARY KEY, b INT, c INT, INDEX(b))

a

b

c

1

1

1

2

2

2

3

3

3

4

4

4

0.共用栈

代码语言:javascript
复制
|-mysql_parse()
|--mysql_execute_command()
|---Sql_cmd_dml::execute()
|----Sql_cmd_dml::execute_inner()

1.基于主键的点查询

这种情况是最特殊的一种,基于主键的点查询只需要和Rocksdb引擎交互一次,找到主键也就找到了所需要的数据。 如 SELECT * FROM t2 WHERE a = 2;

代码语言:javascript
复制
|-SELECT_LEX::optimize()
|--JOIN::optimize()
|---JOIN::make_join_plan()
|----JOIN::extract_func_dependent_tables()
|-----join_read_const_table()
|------read_const()
----------------------
|-handler::ha_index_read_idx_map()
|--handler::index_read_idx_map()
|---ha_rocksdb::index_read_map()
/* key = 2,需要构造slice */
|----ha_rocksdb::index_read_map_impl() /* 判断是否基于主键查询 */
|-----ha_rocksdb::get_row_by_rowid()

如果没有主键(如t1)的话,rocksdb也是会为每行数据创建一个rowid作为主键,实际上,不管有没有用户自定义主键,每张表上都是有主键的,只是显式和隐式的区别。

2.全表扫描

全表扫描需要借助迭代器来完成,所以再初始化扫描的过程中需要初始化迭代器。 如SELECT * FROM t1;

代码语言:javascript
复制
|-JOIN::exec()
|--do_select()
|---sub_select()
|----TableScanIterator::Init()
|-----handler::ha_rnd_init()
|------ha_rocksdb::rnd_init()
/* 这里需要调用成员m_pk_descr的get_first_key方法来确定迭代器的初始位置 */
/* successor()/predecessor()分别计算处于当前key的下一个key和上一个key */
|-------ha_rocksdb::setup_iterator_for_rnd_scan()
|--------Seek() /* rocksdb方法,具体定位数据 */
|----TableScanIterator::Read()
|-----handler::ha_rnd_next()
|------ha_rocksdb::rnd_next()
/* 根据方向进行迭代,rocksdb提供next和prev两种方式。这里拿出KV进行处理(decode等) */
|-------ha_rocksdb::rnd_next_with_direction()
|-----handler::ha_index_or_rnd_end()
|------handler::ha_rnd_end()
|-------ha_rocksdb::rnd_end()

这里有一种特殊情况,当表t只有两列(a primary key,b index key)时,执行全表扫描会通过二级索引进行查询。当然,这里通过二级索引进行查询并不会走'二级索引->主键->数据'的路子,因为只有两列数据,查询二级索引获取主键的过程中已经获得了全部数据,因此不用再通过主键去查询完整的数据。理论上这种形式和直接查主键时等价的,之所以会通过二级索引因该与优化器的实现有关。如SELECT * FROM t2;

3.基于主键的范围查询

范围查询分三种情况 x > a; x < a; a < x < b;其中第三种情况最好处理,因为start_key和end_key已知,另外两种情况只知其一(实际上也没有什么大的差别) 如SELECT * FROM t2 WHERE a < 3;

代码语言:javascript
复制
|-JOIN::init_planner_arrays()
|--TABLE_LIST::fetch_number_of_rows()
|---ha_rocksdb::info()
|----ha_rocksdb::get_range()
|-IndexRangeScanIterator::Read()
|--QUICK_RANGE_SELECT::get_next()
|---handler::ha_multi_range_read_next()
|----handler::multi_range_read_next()
/* 这里会传入start_key/end_key,如果start_key为空,
   就通过索引(这里是主键)查找出第一行符合要求的数据构造start_key
   ha_index_first(),在上述例子中就是找到key=1作为start_key
   end_key为空没有什么关系,我们可以一直读到下一个不符合要求的key为止
*/
|-----ha_rocksdb::read_range_first()
//rocksdb查询方式:storage/rocksdb/rocksdb-range-access.txt
/* 这里面有和循环来读取范围内的数据
   1.移动到正确的初始位置position_to_correct_key()
   2.验证是否使用布隆过滤并设置查询的上下边界ha_rocksdb::check_bloom_and_set_bounds()
   3.注意:这里设置的lower_bound或upper_bound其实是key+1或key-1,所以这两个bound之间差2
   4.构建的lower_bound/upper_bound当然是经过编码的
*/
|------ha_rocksdb::index_read_map_impl()
|-------ha_rocksdb::setup_scan_iterator()
|--------ha_rocksdb::check_bloom_and_set_bounds()

4.基于二级索引的查询

基于二级索引的点查询或范围查询与上述过程是类似的,只是多了一次通过主键回查完整数据的调用(2中所述的特殊情况除外) 如SELECT * FROM t3 WHERE b = 2;

代码语言:javascript
复制
/* 过程有省略 */
|-RefIterator<false>::Read()
|--handler::ha_index_read_map()
|---ha_rocksdb::index_read_map()
|----ha_rocksdb::index_read_map_impl()
|-----ha_rocksdb::read_row_from_secondary_key()
|------ha_rocksdb::get_row_by_rowid()

以t3为例,相较2/3,多的是read_row_from_secondary_key()这一个调用。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0.共用栈
  • 1.基于主键的点查询
  • 2.全表扫描
  • 3.基于主键的范围查询
  • 4.基于二级索引的查询
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档