【发布时间】:2015-02-20 17:41:47
【问题描述】:
我正在尝试构建一个表以搜索来自许多不同表的合并数据。所有列都是字符串。我不确定有什么更快的方法:
- 将所有字符串合并为一列(每个字符串用 | 分隔) 比如“94045|山景|blah|...”
- 制作包含多个字符串列的表格。
我打算进行“LIKE”搜索。例如“select id from SEARCH where col1 like '%view%'”
两种方法的搜索速度有什么区别吗?
【问题讨论】:
我正在尝试构建一个表以搜索来自许多不同表的合并数据。所有列都是字符串。我不确定有什么更快的方法:
我打算进行“LIKE”搜索。例如“select id from SEARCH where col1 like '%view%'”
两种方法的搜索速度有什么区别吗?
【问题讨论】:
我假设 id 是您的主键并且您正在使用 InnoDB。
如果组合字符串小于 InnoDB 单列索引限制 767 字节,则将字符串组合成一列,以便 MySQL 可以扫描单个平面索引。然后,在该单列上创建二级索引。
由于前缀中的通配符,MySQL 仍然需要扫描索引而不是进行二进制搜索来定位 id,但扫描索引比扫描更大的数据页要快。
此外,如果有足够的工作空间 (innodb_buffer_pool_size),MySQL 将在内存中拥有索引,因此它根本不必访问磁盘。
SELECT id FROM table1
WHERE column1 LIKE '%search%'
请注意,单列索引在此处充当覆盖索引,因为 InnoDB 二级索引也始终具有主键。因此,针对二级索引仅选择主键 id 时,会将其视为覆盖索引。
【讨论】:
如果每个分隔的单词都有不同的含义,那么分隔列应该更好。 例如,如果您的数据由邮政编码、街道和描述组成,那么您应该有 3 个不同的列。
这样,如果您知道搜索词应该只在其中一个字段中,您可以将搜索构造为仅查看某些字段。
【讨论】:
如果搜索模式在第一个字符之前有通配符,则无法有效地索引数据以进行快速搜索,因此需要“全数据扫描”。
您可以通过减少扫描的记录数来大大提高性能。就像检查数据以找出邮政编码并对其进行索引搜索(结合疯狂的LIKE 条件)。
【讨论】: