我可以“优化”涉及文本列的查询吗?

吉戈兹

如果我有这个400M行表:

create table my_table
( id int,
  filled tinyint,
  content text not null
) engine=myisam

我可以通过以下方式阻止对内容的额外访问(由于列类型的文本):

select id,if(filled,content,'') from my_table

(填充的是0还是1)?

或者,如果content可以为null,则将

select id,ifnull(content,'') from my_table

会更好(仍会在性能方面,因为会发生空开销)?

里克·詹姆斯

您的问题不准确。可能会连续filled = 1content = 'some text'

如果是,则IF(filled, content, '')有意义。

如果否,则摆脱掉filled并简单地设置content''访问空字符串的成本content很小。

content通常多大如果通常只有数百个字符,则性能差异很小。

不要使用MyISAM,请切换到InnoDB。

你有很多的DELETEs还是UPDATEs如果是这样,则MyISAM的.MYD文件可能会碎片化。这意味着content可能分散在磁盘周围。如果您没有更新或删除,则content“就在那里”,因此实际上可以自由访问。

相反,InnoDB有时会放下TEXTBLOB“关闭记录”。

但是,哪个更好或更坏?离记录(在某些情况下)与碎片(在某些情况下)相比。

您只取一行吗?还是很多这样的行?这是MyISAM和InnoDB实施方式完全不同的另一个领域。MyISAM需要逐步content进入“下一个”行。(我不会去到一个漫长的讨论,其中“下一个”行很可能是。)

底线:不担心优化,但改变InnoDB的(对于很多原因)。

“下一个”行可能在哪里?

MyISAM ...按插入顺序将行添加到.MYD。但是,在更新或删除后,新行/已更改的行往往会首先填补空白,而作为最后的选择则将其追加到文件中。

InnoDB ...行在B + Tree中,由排序PRIMARY KEYBTree被16KB的块阻塞。您有一TEXT列,因此变得更加复杂...

对于“小的” TEXT列,几行可容纳16KB。如果content是1KB的字符串,则最多可将15行放在一个块中。如果它们更大,content则将被“记录外”存储。

块中的行基本上彼此等距。(最大的工作是将块加载到缓存中并找到该块。)

“下一个”(或“上一个”)块仅是磁盘访问权限-参见“ B + Tree”中的“ +”。

当一个块溢出时,它被“拆分”为两个块,每个块都有一些行。新块分配在某个地方,很少相邻。

使用SSD时,所有块彼此“等距”。使用HDD时,旋转延迟和手臂运动会使该模块的时序比其他模块“更近”。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章