面试题答案
一键面试查询实现
假设数据库为MySQL,可使用REGEXP
关键字实现:
SELECT * FROM logs
WHERE message REGEXP '^特定开头字符串.*特定结尾字符串$';
性能优化
- 添加索引:虽然MySQL对正则表达式查询无法充分利用常规索引,但可以考虑对
message
字段建立全文索引。首先修改表结构添加全文索引:
ALTER TABLE logs ADD FULLTEXT(message);
然后使用MATCH AGAINST
语法查询:
SELECT * FROM logs
WHERE MATCH(message) AGAINST('特定开头字符串 特定结尾字符串' IN NATURAL LANGUAGE MODE);
不过这种方式要求查询词在文本中是独立单词,需要根据实际情况调整。
2. 分区表:如果数据量巨大,按一定规则(如日期等)对logs
表进行分区,查询时可以减少扫描的数据量。例如按日期分区:
CREATE TABLE logs (
id INT,
message VARCHAR(255)
)
PARTITION BY RANGE (YEAR(log_date)) (
PARTITION p0 VALUES LESS THAN (2020),
PARTITION p1 VALUES LESS THAN (2021),
PARTITION p2 VALUES LESS THAN (2022)
);
查询时,MySQL会自动定位到相关分区,减少扫描的数据范围。
MySQL执行机制
- 全表扫描:当使用
REGEXP
进行正则表达式定位符查询时,MySQL通常会对表进行全表扫描。因为正则表达式过于灵活,MySQL难以利用索引来优化查询。它会逐行读取message
字段的值,并将其与正则表达式进行匹配,这在大数据量下性能较差。 - 使用索引的限制:MySQL的普通索引是基于比较操作的,而正则表达式涉及复杂的模式匹配,所以普通索引无法直接应用。全文索引虽然能在一定程度上优化文本搜索,但与正则表达式的匹配逻辑还是有差异,只能在特定场景替代部分正则查询。