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

Mysql 我可以吗;“优化”;涉及文本列的查询?,mysql,query-optimization,Mysql,Query Optimization,如果我有这个400M行表: create table my_table ( id int, filled tinyint, content text not null ) engine=myisam 我是否可以通过以下方式防止额外访问内容(由于列类型文本): (填写的是0或1) 或者,如果内容可以为空,则 select id,ifnull(content,'') from my_table 变得更好(仍然是在性能方面,因为会出现零开销)?您的问题不精确。行是否有filled=1和co

如果我有这个400M行表:

create table my_table
( id int,
  filled tinyint,
  content text not null
) engine=myisam
我是否可以通过以下方式防止额外访问内容(由于列类型文本):

(填写的是0或1)

或者,如果内容可以为空,则

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

变得更好(仍然是在性能方面,因为会出现零开销)?

您的问题不精确。行是否有
filled=1
content='some text'

如果是,则
If(已填充,内容为“”)
有意义

如果没有,则去掉
填充的
,只需将
内容
设置为
'
。为
内容
访问空字符串的成本很小

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

不要使用MyISAM,切换到InnoDB

您是否有大量的
删除
更新
?如果是这样,MyISAM的.MYD文件可能会被分割。这意味着
内容可能分散在磁盘上。如果您没有更新或删除,那么
内容
就“在那里”,因此几乎可以自由访问

相反,InnoDB有时会将
文本
BLOB
置于“非记录”状态

但是,哪一个更好还是更坏?记录外(在某些情况下)与碎片化(在某些情况下)

你只拿到一行吗?还是有很多这样的争吵?这是MyISAM和InnoDB实现方式完全不同的另一个领域。MyISAM需要跳过
content
进入“下一行”。(我不会长篇大论地讨论“下一行”可能在哪里。)

一句话:不要担心优化,但要改成InnoDB(有很多原因)

下一行可能在哪里?

MyISAM。。。行按插入顺序添加到.MYD。但是,在更新或删除之后,新的/更改的行往往会首先填补空白,而将附加到文件作为最后手段

InnoDB。。。行位于B+树中,按
主键排序。BTree被16KB块阻塞。您有一个
TEXT
列,因此它变得更复杂

对于“小”文本列,有几行可以容纳16KB。比如说,如果
内容
是1KB的字符串,那么一个块中最多会放入15行。如果它们更大,则
内容
将存储为“非记录”

块中的行之间基本上都是等距的。(最大的努力是将块加载到缓存中并定位块。)

“next”(或“previous”)块只是一个磁盘访问之外的块——请参见“B+树”中的“+”

当一个块溢出时,它被“分割”成两个块,一些行进入每个块。新街区被分配到某个地方,很少相邻


对于SSD,所有块之间的距离都是“相等的”。对于HDD,旋转延迟和手臂运动会使哪个块可能比其他块“更近”的计时变得复杂。

首先,这两个查询的作用不同。你想做什么?我想阻止额外的内容访问(由于列类型的文本),如果它没有填写“额外的内容访问”——在第一个查询中,你选择了所有内容。“还有比这些更好的吗?”---如果您还没有为它们编制索引,那么每个查询都需要进行完整扫描。正确。在表扫描中,我不希望内容在未填充时导致额外的磁盘访问。相关:已接受。顺便说一句,我在哪里可以阅读一些关于“下一行”可能在哪里的信息?@guigoz-我补充了我的答案。如果你想要更多的细节,开始一个新的问题,并把它缩小到你想谈论的引擎。
select id,ifnull(content,'') from my_table