043、TiDB特性_缓存表和分区表

针对于优化器在索引存在时依然使⽤全表扫描的情况下,使⽤缓存表和分区表是提升查询性能的有效⼿段。
在这里插入图片描述

缓存表

  • 缓存表是将表的内容完全缓存到 TiDB Server 的内存中
  • 表的数据量不⼤,⼏乎不更改
  • 读取很频繁
  • 缓存控制: ALTER TABLE table_name CACHE|NOCACHE;
# 使用trace跟踪下
tidb> TRACE SELECT * FROM test.c1;
+-------------------------------------------+-----------------+---
---------+
| operation | startTS |
duration |
+-------------------------------------------+-----------------+---
---------+
| trace | 18:39:25.485266 |
501.582µs |
| ├─session.ExecuteStmt | 18:39:25.485270 |
432.208µs |
| │ ├─executor.Compile | 18:39:25.485281 |
132.616µs |
| │ └─session.runStmt | 18:39:25.485433 |
249.488µs |
| │ └─UnionScanExec.Open | 18:39:25.485572 |
72.776µs |
| │ ├─TableReaderExecutor.Open | 18:39:25.485575 |
13.24µs |
| │ ├─buildMemTableReader | 18:39:25.485605 |
3.283µs |
| │ └─memTableReader.getMemRows | 18:39:25.485615 |   # memTableReader.getMemRows 表示从缓存取数
20.558µs |
| ├─*executor.ProjectionExec.Next | 18:39:25.485712 |
12.911µs |
| │ └─*executor.UnionScanExec.Next | 18:39:25.485714 |
3.823µs |
| └─*executor.ProjectionExec.Next | 18:39:25.485733 |
8.943µs |
| └─*executor.UnionScanExec.Next | 18:39:25.485735 |
1.33µs |
+-------------------------------------------+-----------------+---
---------+
12 rows in set (0.00 sec)

小表缓存-原理

在这里插入图片描述

缓存租约

  • 租约时间内,无法进行写操作
    在这里插入图片描述

  • 租约到期,数据过期

  • 写操作不再被阻塞

  • 读写直接到TiKV节点上执行
    在这里插入图片描述

  • 数据更新完毕,租约继续开启

在这里插入图片描述

应用场景

  • 每张缓存表的大小限制为64MB
  • 适用于查询频繁、数据量不大、修改极少的场景
  • 在租约(tidb_table_cache_lease) 时间内,写操作会被阻塞
  • 当租约到期(tidb_table_cache_lease)时,读性能会下降
  • 不支持对缓存表直接做DDL操作,需要先关闭
  • 对于表加载较慢或者极少修改的表,可以适当延长tidb_table_cache_lease保持读性能稳定

分区表

分区类型与适用场景

  • range: 分区剪裁,节省IO开销
  • Hash: 用于大规模写入的情况下将数据打散,平均地分配到各个分区里
Range分区表
create table t1(x int) partition by name(x) (
partition p0 values less than(5),
partition p1 values less than (10));
)

分区类型与适⽤场景

  • Range

分区裁剪, 节省 I/O 开销

/* Range Partition t1 */
drop table if exists test.t1;
create table test.t1 (x int) partition by range (x) (
 partition p0 values less than (5),
 partition p1 values less than (10));
insert into test.t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
/* Check Partition Pruning */
explain select * from test.t1 where x between 1 and 4;

查看执行计划
mysql> explain select * from test.t1 where x between 1 and 4;
+-------------------------+-----------+-----------+------------------------+------------------------------------+
| id                      | estRows   | task      | access object          | operator info                      |
+-------------------------+-----------+-----------+------------------------+------------------------------------+
| TableReader_9           | 12288.00  | root      |                        | data:Selection_8                   |
| └─Selection_8           | 12288.00  | cop[tikv] |                        | ge(test.t1.x, 1), le(test.t1.x, 4) |
|   └─TableFullScan_7     | 491520.00 | cop[tikv] | table:t1, partition:p0 | keep order:false                   |
+-------------------------+-----------+-----------+------------------------+------------------------------------+
3 rows in set (0.03 sec)
/* Check regions */
show table test.t1 regions;
mysql> show table test.t1 regions;
+-----------+-----------+---------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
| REGION_ID | START_KEY | END_KEY | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS |
+-----------+-----------+---------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
|      5019 | t_79_     | t_80_   |      5020 |            1001 | 5020  |          0 |             0 |          0 |                   67 |           877551 |
|      1002 | t_80_     |         |      1003 |            1001 | 1003  |          0 |             0 |          0 |                   24 |           421921 |
+-----------+-----------+---------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
2 rows in set (0.02 sec)
  • Hash

可以⽤于⼤规模写⼊的情况下将数据打散, 平均地分配到各个分区⾥

/* Hash Partition t1 */
drop table if exists test.t1;
CREATE TABLE test.t1 (x INT)
 PARTITION BY HASH(x)
 PARTITIONS 4;

insert into test.t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;
insert into test.t1 select * from test.t1;

查看分区的执行计划

  • 默认是通过mod方式分配分区
/* Check Partition Distribution */

explain select * from test.t1 where x=0;
explain select * from test.t1 where x=1;
explain select * from test.t1 where x=2;
explain select * from test.t1 where x=3;
explain select * from test.t1 where x=4;
explain select * from test.t1 where x=5;
explain select * from test.t1 where x=6;
explain select * from test.t1 where x=7;
explain select * from test.t1 where x=8;
explain select * from test.t1 where x=9;
/* Negative */
explain select * from test.t1 where x between 7 and 9;
mysql> explain select * from test.t1 where x between 7 and 9;
+------------------------------+----------+-----------+------------------------+------------------------------------+
| id                           | estRows  | task      | access object          | operator info                      |
+------------------------------+----------+-----------+------------------------+------------------------------------+
| PartitionUnion_10            | 750.00   | root      |                        |                                    |
| ├─TableReader_13             | 250.00   | root      |                        | data:Selection_12                  |
| │ └─Selection_12             | 250.00   | cop[tikv] |                        | ge(test.t1.x, 7), le(test.t1.x, 9) |
| │   └─TableFullScan_11       | 10000.00 | cop[tikv] | table:t1, partition:p0 | keep order:false, stats:pseudo     |
| ├─TableReader_16             | 250.00   | root      |                        | data:Selection_15                  |
| │ └─Selection_15             | 250.00   | cop[tikv] |                        | ge(test.t1.x, 7), le(test.t1.x, 9) |
| │   └─TableFullScan_14       | 10000.00 | cop[tikv] | table:t1, partition:p1 | keep order:false, stats:pseudo     |
| └─TableReader_19             | 250.00   | root      |                        | data:Selection_18                  |
|   └─Selection_18             | 250.00   | cop[tikv] |                        | ge(test.t1.x, 7), le(test.t1.x, 9) |
|     └─TableFullScan_17       | 10000.00 | cop[tikv] | table:t1, partition:p3 | keep order:false, stats:pseudo     |
+------------------------------+----------+-----------+------------------------+------------------------------------+
10 rows in set (12.69 sec)

查看region分布情况

/* Check regions */
# 查看对应的region情况,在4个region上
mysql> show table test.t1 regions;
+-----------+-----------+---------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
| REGION_ID | START_KEY | END_KEY | LEADER_ID | LEADER_STORE_ID | PEERS | SCATTERING | WRITTEN_BYTES | READ_BYTES | APPROXIMATE_SIZE(MB) | APPROXIMATE_KEYS |
+-----------+-----------+---------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
|      9003 | t_84_     | t_85_   |      9004 |            1001 | 9004  |          0 |      18449249 |   14117466 |                   13 |           141205 |
|      9005 | t_85_     | t_86_   |      9006 |            1001 | 9006  |          0 |      18443067 |   14024508 |                   10 |            58475 |
|      9007 | t_86_     | t_87_   |      9008 |            1001 | 9008  |          0 |      12295360 |    8703102 |                    5 |            27228 |
|      1002 | t_87_     |         |      1003 |            1001 | 1003  |          0 |      12295959 |    9218671 |                    4 |            26666 |
+-----------+-----------+---------+-----------+-----------------+-------+------------+---------------+------------+----------------------+------------------+
4 rows in set (2 min 46.43 sec)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值