伍佰目录 短网址
  当前位置:海洋目录网 » 站长资讯 » 站长资讯 » 文章详细 订阅RssFeed

Mysql的表中含有Blob字段对性能的影响有几何?

来源:本站原创 浏览:130次 时间:2022-09-23

  在不少公司的mysql的开发规范中,会表中对blob ,text字段的情况,进行严格的审核。对含有大字段的表,有些公司的dba甚至需要开发总监级别以上的领导同意,才会在生产环境创建含大字段的表。 但大字段是否真的是洪水猛兽?大字段到底是如何存储在数据页中,以及大字段到底影响了哪些性能? 估计大多数的dba都没有进行过仔细的评估。
       带着这些问题,作者分析了一下mysql的源码并行了简单的测试。
简单说一下包含大字段的表的insert的操作过程, 大致是这样。
a. 首先通过函数dtuple_convert_big_rec 来判断是否需要转换为big_record. 该函数的作用就是将字段非常长的字段(有个标准,大概是8K左右)从行中剥离,使其他字段组成的行变成可以按照普通行存放。


b. 插入剥离大字段的行。


c. 通过函数row_ins_index_entry_big_rec_func 插入该行的大字段。


     因此,当一个表中虽然有大字段,但该大字段列存放的值长度比较小的时候,是不需要以big_rec的形式来存放的。虽然是一个含有大字段的行,但行的总体字符长度较短时,则按普通的行存放。 Blob 字段类型的基础类型,实际上跟varchar的类型相同。所以,当某行的大字段存放的值的长度较长时,以big_rec独立存放,当某行的大字段存放的值的长度很小时,则以普通行的方式,跟其他字段一起存放。
     同时,通过上面的分析,对于insert一个长度较长的行,当需要以big_rec方式存放时,实际上进行了两次存数据的操作。第一次是剥离了大字段后,其他字段的存放。 第二次是大字段的独立存放。
以下是dtuple_convert_big_rec的注释,请阅读。
/**************************************************************//**
Moves parts of long fields in entry to the big record vector so that
the size of tuple drops below the maximum record size allowed in the
database. Moves data only from those fields which are not necessary
to determine uniquely the insertion place of the tuple in the index.
@return own: created big record vector, NULL if we are not able to
shorten the entry enough, i.e., if there are too many fixed-length or
short fields in entry or the index is clustered */
big_rec_t*
dtuple_convert_big_rec(
/*===================*/
 dict_index_t* index, /*!< in: index */
 upd_t*  upd, /*!< in/out: update vector */
 dtuple_t* entry, /*!< in/out: index entry */
 ulint*  n_ext) /*!< in/out: number of
    externally stored columns */
{
 …………………………………………………………………………………………………………………………………………..
…………………………………………………………………………………………………………………………………………………….
    
}

以下是row_ins_index_entry_big_rec_func 函数的注释,该函数的作用是存储需要独立存放的字段。 真正执行存放的函数为btr_store_big_rec_extern_fields
/***************************************************************//**
Tries to insert the externally stored fields (off-page columns)
of a clustered index entry.
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
dberr_t
row_ins_index_entry_big_rec_func(
/*=============================*/
 const dtuple_t*  entry, /*!< in/out: index entry to insert */
 const big_rec_t* big_rec,/*!< in: externally stored fields */
 ulint*   offsets,/*!< in/out: rec offsets */
 mem_heap_t**  heap, /*!< in/out: memory heap */
 dict_index_t*  index, /*!< in: index */
 const char*  file, /*!< in: file name of caller */
#ifndef DBUG_OFF
 const void*  thd,    /*!< in: connection, or NULL */
#endif /* DBUG_OFF */
 ulint   line) /*!< in: line number of caller */
{
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 error = btr_store_big_rec_extern_fields(
  &pcur, 0, offsets, big_rec, &mtr, BTR_STORE_INSERT);
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
}

下面是实际执行存放big_rec的函数的注释。
/*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec.  The extern flags in rec will have to be set beforehand.
The fields are stored on pages allocated from leaf node
file segment of the index tree.

TODO: If the allocation extends the tablespace, it will not be redo logged, in
any mini-transaction.  Tablespace extension should be redo-logged, so that
recovery will not fail when the big_rec was written to the extended portion of
the file, in case the file was somehow truncated in the crash.

@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
dberr_t
btr_store_big_rec_extern_fields(
/*============================*/
 btr_pcur_t* pcur,  /*!< in/out: a persistent cursor. if
     btr_mtr is restarted, then this can
     be repositioned. */
 const upd_t* upd,  /*!< in: update vector */
 ulint*  offsets, /*!< in/out: rec_get_offsets() on
     pcur. the "external storage" flags
     in offsets will correctly correspond
     to rec when this function returns */
 const big_rec_t*big_rec_vec, /*!< in: vector containing fields
     to be stored externally */
 mtr_t*  btr_mtr, /*!< in/out: mtr containing the
     latches to the clustered index. can be
     committed and restarted. */
 enum blob_op op)  /*! in: operation code */
{
…….………………………………………………………………………………………………………………………………………………………………
}

通过上面的源码获知,对于包含大字段的insert, 需要多走一个存数据的操作,势必影响了insert的速度。
但对于查询呢,是否会有影响?
在做测试之前,作者的做一下猜想
a. 因为大字段是独立存储,因此如果不查该大字段,也不使用大字段的字段作为结果集,在相同记录数下,含有大字段的表,跟不含有大字段的表,不管是走全表扫描,还是走索引查找,性能几乎一样。
b. 如果对大字段全范围查找,大字段值的长度越长,长记录的数量越多,查找越慢。
c. 建立两个表,一个表的其中一个字段是varchar(100),另外一个表的其中一个字段为blob, 其他字段均相同,然后对这两个表进行插入完全相同的数据100万行,然后进行各种方式的数据查找,性能应该几乎一样。

  限于排版,测试过程省略,有兴趣的朋友请自行测试。。。。


 通过测试,以上猜想均被实验验证!


  推荐站点

  • At-lib分类目录At-lib分类目录

    At-lib网站分类目录汇集全国所有高质量网站,是中国权威的中文网站分类目录,给站长提供免费网址目录提交收录和推荐最新最全的优秀网站大全是名站导航之家

    www.at-lib.cn
  • 中国链接目录中国链接目录

    中国链接目录简称链接目录,是收录优秀网站和淘宝网店的网站分类目录,为您提供优质的网址导航服务,也是网店进行收录推广,站长免费推广网站、加快百度收录、增加友情链接和网站外链的平台。

    www.cnlink.org
  • 35目录网35目录网

    35目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向35目录推荐、提交优秀网站。

    www.35mulu.com
  • 就要爱网站目录就要爱网站目录

    就要爱网站目录,按主题和类别列出网站。所有提交的网站都经过人工审查,确保质量和无垃圾邮件的结果。

    www.912219.com
  • 伍佰目录伍佰目录

    伍佰网站目录免费收录各类优秀网站,全力打造互动式网站目录,提供网站分类目录检索,关键字搜索功能。欢迎您向伍佰目录推荐、提交优秀网站。

    www.wbwb.net