【发布时间】:2021-05-17 02:56:59
【问题描述】:
我在处理一个包含许多记录的大表时遇到了一个问题(顺便说一下 MySQL)。
我有两种情况。第一个是具有主键和 18 个不同 varchar 字段的单个表。
| id | Field1 | Field2 | Field18 |
|---|---|---|---|
| 1 | abc | abc | abc |
| 2 | def | def | def |
| 100 | xyz | xyz | xyz |
第二种情况是我有一个表格,它以不同的方式组织所有信息:
| id_record | field_name | value |
|---|---|---|
| 1 | field1 | abc |
| 1 | field2 | abc |
| 1 | field3 | abc |
| 2 | field1 | def |
| 100 | field18 | xyz |
首先我有一个固定的结构(没有灵活性)并且可能有很多空格。在第二种解决方案中,我可以轻松添加新字段,但表格会快速增长。
在一些测试中,我运行的两个测试都存储了大约 200 000 条记录。但随着我的成长(我用 500 000 和 1M 进行测试),在第二种情况下事情变得缓慢。
第二个 id_record 和 field_name 是索引,值是全文。但这并没有太大帮助。
当我尝试合并两个匹配项时,事情变得特别慢:
select f1.id_record from table f1 where f1.field = 'field1' and f1.value like '%abc%' and f1.id_record in (
select f2.id_record from table f2 where f2.field = 'field18' and f2.value like '%abc%'
);
或
select f1.id_record from table f1, table f2 where f1.field = 'field1' and f2.field = 'field18' and f1.id_record = f2.id_record and f1.value like '%abc%' and f2.value like '%abc%';
关于如何在第二种情况下表现更好的任何想法?或者对于如何更好地构建此类数据有什么新想法?
【问题讨论】:
-
如果您熟悉python,那么我强烈建议您将mysql-connecter与python一起使用。您可以编写一个脚本,将任何类型的文件作为输入并将该数据存储到 MySQL 中。
-
您创建了哪些索引?第二种情况是可怕的交叉连接,所以它可能不是你想要的。
-
我正在使用 PHP,所以它不起作用。我为 id_record 和
field列使用单独的索引,为value列使用全文 -
您的典型查询是否在某些列中查找子字符串?这些子字符串是“单词”吗?
-
我可能会搜索全文或只是其中的一部分,并且文本是一个句子(我很少会存储全文,但可能偶尔会发生一次)。这实际上不是我主要关心的问题。这是性能与灵活性。如果我使用传统表格,我需要设置的列数量有限。所以我最终可能会得到很多空值或用完插槽。使用第二种方法我有更大的灵活性,我只存储有效数据(不需要存储空值),但我很快就会增长该表并且性能开始下降。