mysqlの一時テーブルとパーティションテーブル

メモリ一時テーブルとテーブル

  • メモリテーブルは、構築されたテーブルの構文テーブル...エンジン=メモリを作成し、テーブルメモリエンジンの使用を意味します。このデータテーブルは、システムの再起動時にクリアされ、メモリに保存されているが、テーブル構造がまだそこにあるされています。これらの2つの機能に加えて、ビューの点から他の特徴は、それは通常のテーブルには、より「奇妙」に見えます

  • 一時表は、あなたがエンジンのさまざまな種類のを使用することができます。書き込みデータがディスクに書き込まれるときには、InnoDBエンジンや一時テーブルのMyISAMエンジンを使用している場合。もちろん、あなたも一時テーブルメモリのエンジンを使用することができます。

  • 一時的なテーブル機能

  1. 内蔵テーブルの構文は、一時テーブルを作成することです....
  2. 一時テーブルは、それが唯一の他のスレッドには見えないセッションにアクセスすることができます作成​​されます。したがって、図テンポラリテーブル作成されたセッションTで、セッションBに閲覧できません。
  3. 同じ名前の一時テーブルは通常のテーブルとすることができます。
  4. タイムテーブルと同じ名前を持つ、通常のセッションで一時テーブルは、ショーが一時テーブルにアクセスするための書類、およびCRUD文を作成し、あります。
  5. ショーテーブルは一時テーブルを表示しませんコマンド。

一時テーブルにのみそれを作成したセッションにアクセスし、そうすることができますので、このセッションが終了したときに、一時テーブルは自動的に削除されます。これは、一時テーブルはこのシーンを最適化する参加特に適している、この機能によるものです。

create temporary table temp_t like t1;
alter table temp_t add index(b);
insert into temp_t select * from t2 where b>=1 and b<=2000;
select * from t1 join temp_t on (t1.b=temp_t.b);
  1. 一時テーブルは、同じ名前の別のセッションで複数のセッションが同時に存在する場合、最適化を結合を実行、テーブル名を繰り返すことを心配していないテーブルを構築するための課題は失敗しました。原因。
  2. あなたは、データ削除の問題を心配する必要はありません。共通テーブル場合、処理実行クライアントに断線異常が発生した場合、またはデータベースが発生し、異常再起動するだけでなく、具体的には表中に生成された中間データをきれいにします。一時的なテーブルに自動的に回復しますので、この追加の操作は必要ありません。

一時テーブルの応用

  • クロスデータベースクエリのサブライブラリーのサブテーブルシステム

  • 通常、サブライブラリーサブテーブルのシーン分散液は、それが異なる論理データベース・インスタンスへの大きなテーブルにあります。たとえば。大きなテーブルHTは、フィールドFに応じて、サブテーブル1024に分割した後、インスタンスデータベース32に分配されます。

  • 分区key的选择是以“减少跨库和跨表查询”为依据的。如果大部分的语句都会包 含f的等值条件,那么就要用f做分区键。这样,在proxy这一层解析完SQL语句以后,就能确定将这条语句路由到哪个分表做查询。 比如

    select v from ht where f=N;

    这时,我们就可以通过分表规则(比如,N%1024)来确认需要的数据被放在了哪个分表上。这种语句只需要访问一个分表,是分库分表方案最欢迎的语句形式了。

    但是,如果这个表上还有另外一个索引k,并且查询语句是这样的:

    select v from ht where k >= M order by t_modified desc limit 100;

    这时候,由于查询条件里面没有用到分区字段f,只能到所有的分区中去查找满足条件的所有 行,然后统一做order by 的操作。这种情况下,有两种比较常用的思路:

    1. 在proxy层的进程代码中实现排序,对proxy端的压力比较大,尤其是很容易出现内存不够用和CPU瓶颈的问题。

    2. 把各个分库拿到的数据,汇总到一个MySQL实例的一个表中,然后在这个汇总实例上做逻辑操作。

      • 在汇总库上创建一个临时表temp_ht,表里包含三个字段v、k、t_modifified;

      • 在各个分库上执行

        select v,k,t_modified from ht_x where k >= M order by t_modified desc limit 100;
      • 把分库执行的结果插入到temp_ht表中;

      • 执行

        select v from temp_ht order by t_modified desc limit 100;

为什么临时表可以重名

create temporary table temp_t(id int primary key)engine=innodb;

执行这个语句的时候,MySQL要给这个InnoDB表创建一个frm文件保存表结构定义,还要有地方保存表数据。

这个frm文件放在临时文件目录下,文件名的后缀是.frm,前缀是“#sql{进程id}_{线程id}_序列 号”。你可以使用select @@tmpdir命令,来显示实例的临时文件目录。

这个进程的进程号是1234,session A的线程id是4,session B的线程id是5。所以session A和session B创建的临时表,在磁盘上的文件不会重名

MySQL维护数据表,除了物理上要有文件外,内存里面也有一套机制区别不同的表,每个表都对应一个table_def_key。 对于临时表,table_def_key在“库名+表名”基础上,又加入了“server_id+thread_id”。

也就是说,session A和sessionB创建的两个临时表t1,它们的table_def_key不同,磁盘文件名 也不同,因此可以并存。

分区表的引擎层行为

ATE TABLE   `t` (
        `ftime` datetime    NOT NULL,
        `c` int(11) DEFAULT NULL,
        KEY (`ftime`)
)   ENGINE=InnoDB   DEFAULT CHARSET=latin1
PARTITION   BY  RANGE   (YEAR(ftime))
Û ॔ګդᎱ
B
7 (PARTITION    p_2017  VALUES  LESS    THAN    (2017)  ENGINE  =   InnoDB,
8   PARTITION   p_2018  VALUES  LESS    THAN    (2018)  ENGINE  =   InnoDB,
9   PARTITION   p_2019  VALUES  LESS    THAN    (2019)  ENGINE  =   InnoDB,
10 PARTITION    p_others    VALUES  LESS    THAN    MAXVALUE    ENGINE  =   InnoDB);
11 insert   into    t   values('2017-4-1',1),('2018-4-1',1);

初始化表的时候,只插入了两行数据,sessionA的select语句对ftime这两个记录之间的间隙加了锁,间隙和加锁状态如图:

也就是说,2017-4-1和2018-4-1这两个记录之间的间隙会被锁住,那么sessionB的两条插入语句都应该进入锁等待状态。但是从效果上看,第一个insert语句是可以执行成功的,因为对于引擎来说,p2018和p2019是不同的表,2017的下一个记录不是2018-4-1而是p2018中的supremum,所以在t1时刻索引如图:

由于分区表的规则,sessionA只操作了p2018,sessionB要插入2018-2-1是可以的但要写入2017-12-1要等待sessionA的间隙锁。

对于MYISAM引擎:

因为在sessionA中,sleep了100秒,由于myisam只支持表锁,所以这条update会锁住整个表t的读,但是结果是,B的第一条语句是可以执行的,第二条语句才进入锁等待状态。

这是myisam表锁只在引擎层实现的,sessionA加的表锁,是所在p2018上,因此只会堵住分区上执行的查询,落到其他分区的查询不受影响。这样看来,分区表还不错,为什么不用呢,我们使用分区表的一个原因就是单表过大,那么不使用分区表,就要使用手动分表的方式。

手动分表需要创建t_2017,t_2018,t_2019,也就是找到需要更新的所有分表,依次执行,这和分区表无实质的差别,两者一个由serverceng决定使用哪个分区,一个由应用层代码决定使用哪个分表,因此,从引擎层看无实际差别。其实主要区别是在server层:打开表行为。

分区策略

每当第一次访问一个分区表时,mysql需要把所有分区都访问一遍:如果分区很多,比如查过了1000个,mysql启动的时候,open_files_limit默认为1024,那么就会在访问表的时候,由于打开了所有文件,超过了上限而报错。

mysiam使用的分区策略成为通用分区策略,每次访问分区都是有server层控制。有比较严重的性能问题。

innodb引擎引入了本地分区策略,是在innodb内部自己管理打开分区的行为。

分区表的server层行为

从server层看,一个分区表就是一个表。

虽然B只操作2017分区,但是由于A持有整个表t的mdl锁,导致了B的alter语句被堵住。如果是使用普通分表,不会跟另外一个分表上的查询语句出现MDL冲突。

小结:

  1. mysql在第一次打开分区表的时候,需要访问所有分区
  2. 在server层,认为这是同一张表,因此所有分区公用MDL锁
  3. 在引擎层,认为这是不同的表,因此在MDL锁之后,会根据分区表规则,只访问必要的分区。

分区表应用场景

分区表的优势是对业务透明,相对于用户分表来说,使用分区表的业务代码更简洁,分区表可以很方便的清理历史数据。

alter table t drop partition 操作是删除分区文件,效果跟drop类似,与delete相比,优势是速度快,对系统影响小。

おすすめ

転載: www.cnblogs.com/jimmyhe/p/11241929.html