2026年03月20日/ 浏览 1
MySQL的FULLTEXT索引是解决模糊搜索的关键。在文章表中,我们对搜索字段建立联合索引:
sql
ALTER TABLE articles
ADD FULLTEXT INDEX ft_search (title, keywords, description, content);
查询时采用MATCH() AGAINST()语法:
php
$searchTerm = "技术干货";
$sql = "SELECT id, title,
MATCH(title, keywords, description, content) AGAINST(? IN BOOLEAN MODE) AS relevance
FROM articles
WHERE MATCH(title, keywords, description, content) AGAINST(? IN BOOLEAN MODE)
ORDER BY relevance DESC";
注意:
1. 中文搜索需设置ft_min_word_len=2并重启MySQL
2. BOOLEAN MODE支持+关键词 -排除词的高级搜索
3. 定期执行OPTIMIZE TABLE articles修复索引碎片
传统LIMIT 100000,20在百万级数据下需遍历前10万条记录。解决方案:
php
// 采用游标分页(Cursor-based Pagination)
$lastId = isset($GET[‘lastid’]) ? (int)$GET[‘lastid’] : 0;
$pageSize = 20;
$sql = “SELECT id, title
FROM articles
WHERE MATCH(title,…) AGAINST(?)
AND id > ?
ORDER BY id ASC
LIMIT ?”;
$stmt = $pdo->prepare($sql);
$stmt->execute([$searchTerm, $lastId, $pageSize]);
前端响应中返回最后一条记录的ID:
json
{
"data": [...],
"next_page": "search.php?q=关键词&last_id=12345"
}
通过AJAX实现搜索结果的动态加载:
javascript
// 初始化搜索
function doSearch(keyword, lastId = 0) {
fetch(/api/search?q=${encodeURIComponent(keyword)}&last_id=${lastId})
.then(res => res.json())
.then(data => {
renderResults(data.items);
if (data.hasmore) {
setupLoadMore(data.lastid);
}
});
}
// 滚动加载更多
function setupLoadMore(lastId) {
window.onscroll = () => {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight – 500) {
doSearch(currentKeyword, lastId);
}
};
}
在100万条测试数据环境下:
– 传统分页:翻页到100页时查询耗时4.7秒
– 游标分页:任意翻页耗时稳定在0.2秒内
– 内存消耗从380MB降至15MB以下
preg_replace在PHP端处理而非前端正则通过以上优化,我们成功构建出毫秒级响应的百万数据搜索引擎。核心在于理解MySQL索引机制、避开深分页陷阱,并保持前后端高效协作。现在,是时候给你的用户提供丝滑的搜索体验了!