查询非常慢的longtext字段innodb表

时间:2012-10-12 16:42:06

标签: performance innodb longtext

嗯,最重要的是,对不起我的英语。我尝试在表中进行查询,用户可以包含一些文本,如博客页面。用户可以以html格式设计内容。在我的表中,它存储如下:

Estadísticas<br />
<table border="0">
<tbody>
<tr>
<td>Columna 1</td>
<td>Columna 2</td>
</tr>
<tr>
<td>Columna 3<br /></td>
<td>Columna 4<br /></td>
</tr>
</tbody>
</table>

我必须在该内容中提供用户所需的全部内容。字段'texto'(我正在使用它)是一个longtext字段,表是innodb。我不能使用全文搜索,因为它只适用于myisam表。我将查询作为:

"SELECT * FROM texto WHERE texto like '%$variable%'"

但查询非常非常慢,需要一段时间。该表有849条记录,这并不大。如果我在phpmyadmin中写相同的查询也需要非常长的时间。但是这个领域有很多记录,有些记录有视频html,表格,图像,但就像上面这样的文字。

我能做什么?如何才能提高查询的性能?我感谢你的帮助。非常感谢。再一次,抱歉我的英语。

1 个答案:

答案 0 :(得分:1)

不幸的是,您无法从您拥有的结构中获得更多 - 任何群集或非群集索引都无法处理like '%...'查询。最好的解决方案可能是将您的数据导出到某个全文搜索引擎(例如SOLR)并使用此引擎来完成用户查询。如果不可能,那么另一个解决方案就是创建一个tokens表,它将扮演文本索引的角色:

create table tokens(
  token varchar(100) not null,
  docid int not null references testdo(id),
  constraint PK_tokens primary key (token, docid)
);

其中docid引用您的数据表(我将其命名为testdo)。

然后你需要通过一些常见的html表达式来分割用户博客帖子来填充tokens表,例如:

insert ignore into tokens values
('Estad', 1),
('Columna 1', 1),
('Columna 2', 1),
('Estad', 1);

注意ignore关键字,它会默默地忽略可能出现的任何重复项。如果tokens表填充了数据,您可以将查询修改为:

select * from testdo d 
  inner join tokens t on t.docid = d.id where t.token like 'Col%'

它应该执行得更快,因为它使用索引和键查找。

PS。您可以通过添加计数列来改进tokens表,该计数列将保留文档中给定单词的出现次数。然后,您可以按此列对结果进行排序,使其与搜索字词更相关。