mysql SELECT
如何从包含一个或多个TEXT
列的表中获取?
假设此查询:
SELECT content FROM posts WHERE id = 1
据我所知,TEXT
类型存储在磁盘中并且在表中有一个指针。那么这个查询如何运作呢?
哪种情况可以?
1 :MySQL加载与此表相关的所有文本,然后开始在表中搜索。找到#1,获取内容并返回行。 (预加载所有TEXT
)
2 :MySQL在表中搜索,找到#1,从磁盘加载与当前匹配行相关的特定TEXT
并返回行。 (像懒人加载!!)
或者MySQL可能以另一种方式工作!
以及包含TEXT
列的非常大的表格如何减少SELECT
和阅读速度?
答案 0 :(得分:1)
执行查询时,谓词包含索引列。 假设您的索引是主键上的B树。然后遍历索引/树,直到到达指向工作负载(元组/行)的指针。您将从磁盘读取整行。
我有一个范围:id> x和id< y,如果索引是聚集的(这样B-Tree的叶节点包含顺序存储在磁盘上的元组,那么它会找到id = x的有效负载并顺序扫描磁盘,直到达到id = y - 1。 / p>
所以我没有看到,如果一个预测列是TEXT或VARCHAR,除了因为TEXT具有可变大小而需要在该特定列上建立索引的事实,您可能需要在大小的前缀上限制索引
答案 1 :(得分:1)
我猜你的问题是错的。
以及如何在其中包含TEXT列的非常大的表,可以降低SELECT和读取速度吗?
你可能想要增加而不是降低阅读速度。
如果您的TEXT字段包含大量数据,那么您可以通过使用更好的硬件并使SQL服务器与您的应用程序位于同一硬件上来提高速度,以便没有网络流量。 SQL服务器的缓存应该很大。然后可以更快地获取最近使用的数据,因为它存储在RAM存储器中而不是存储在硬盘驱动器上。
答案 2 :(得分:1)
如果没有索引可用于查找" id = 1",是的,MySQL会在它找到" id = 1"之前加载所有内容,不幸的是你的选项1。
您可以测试它以查看系统上是否为真(不同的MySQL版本/数据库引擎可能会有不同的结果):
1)创建一个包含两列的表test1 fno int 数据文本
2)用一些真正的大文本填充表格,使用唯一的fno和文本,这样你就可以在以下查询中返回一行。
3)使用以下方法搜索表格:
select sql_no_cache len, data from test1 where fno = 10000;
select sql no_cache len, data from test1 where data like 'tex10000%';
你会看到他们的跑步时间非常接近。您可以按不同的顺序重新运行它们,以确保缓存不会影响结果。
如果MySQL仅在WHERE之后加载文本列,则第一个查询应该比第二个查询快得多,因为它不需要或加载WHERE的数据列。
当没有索引可用时,MySQL服务器会要求db Engine返回WHERE的所有列。 (如果可以使用索引,MySQL将要求db Engine使用索引并仅返回匹配的行,并在需要时进一步处理这些行的WHERE过滤)。
要解决此问题,您需要在fno上创建索引。你会看到第一个查询在索引之后会非常快。如果无法完全避免表扫描并且您不想搜索文本列(数据),则可以将文本列移动到另一个表,并使用唯一键将其链接到主表,如下所示:
文件表: FNO 瞎话 FNAME
filedata表: 瞎话 数据
然后搜索:
select fno, data from files left join filedata using (fid) where fname like '/tmp/aaa.txt';
答案 3 :(得分:0)
看来,你真的需要更多关于如何MySQL Indexes work的背景信息。
您应该为任何要使用WHERE
,ORDER BY
,JOIN
,GROUP BY
等的列添加索引.MySQL将使用索引您将放在id
上解析示例中的WHERE id=1
过滤条件。如果在这种情况下你没有id
的索引,那么MySQL需要全表扫描才能找到符合你标准的记录,你不希望这种情况发生。