汽车广告网站通知功能:批量获取匹配saved_search_id的SQL方案
嘿,我完全懂你现在的痛点——几千条保存的搜索逐个执行查询,效率肯定拉胯。咱们换个思路,用单条SQL批量找出所有匹配新车的saved_search_id,不用再循环跑查询了!
方案1:直接解析URL参数批量匹配(无需修改表结构)
假设你新增的车辆参数是已知的(比如type=0、price=8000、color='red'),我们可以直接在saved_search表中解析每条记录的search_url,和新车参数做对比,一次性筛选出匹配的ID。
以MySQL为例,用字符串函数解析URL参数:
-- 先定义新车参数(实际使用时替换为新增车辆的真实值,或者从Car表中查询) SET @new_type = 0; SET @new_price = 8000; SET @new_color = 'red'; SELECT saved_search_id FROM saved_search WHERE -- 匹配type参数(如果搜索中包含type) (LOCATE('type=', search_url) = 0 OR SUBSTRING_INDEX(SUBSTRING_INDEX(search_url, 'type=', -1), '&', 1) = @new_type) -- 匹配price_max:新车价格≤搜索设置的最高价(如果搜索中包含price_max) AND (LOCATE('price_max=', search_url) = 0 OR @new_price <= SUBSTRING_INDEX(SUBSTRING_INDEX(search_url, 'price_max=', -1), '&', 1)) -- 匹配color参数(如果搜索中包含color) AND (LOCATE('color=', search_url) = 0 OR SUBSTRING_INDEX(SUBSTRING_INDEX(search_url, 'color=', -1), '&', 1) = @new_color);
如果用PostgreSQL,正则解析会更灵活:
WITH new_car AS ( SELECT 0 AS type, 8000 AS price, 'red' AS color ) SELECT s.saved_search_id FROM saved_search s CROSS JOIN new_car c WHERE (NOT s.search_url ~ 'type=' OR (regexp_match(s.search_url, 'type=([^&]+)'))[1]::int = c.type) AND (NOT s.search_url ~ 'price_max=' OR c.price <= (regexp_match(s.search_url, 'price_max=([^&]+)'))[1]::int) AND (NOT s.search_url ~ 'color=' OR (regexp_match(s.search_url, 'color=([^&]+)'))[1] = c.color);
方案2:提前解析URL到表字段(性能最优,推荐)
如果能修改saved_search表结构,建议新增type、price_max、color三个字段,在保存搜索时就解析URL参数存入这些字段。这样查询时可以直接利用索引,性能提升非常明显:
- 先修改表结构:
ALTER TABLE saved_search ADD COLUMN type INT NULL, ADD COLUMN price_max INT NULL, ADD COLUMN color VARCHAR(50) NULL;
保存搜索时,解析URL参数并存入新字段(比如后端代码处理,或者用数据库触发器)。
新增车辆时,直接关联查询:
-- 假设新车数据来自Car表最新新增的记录 SELECT s.saved_search_id FROM saved_search s JOIN Car c ON c.car_id = (SELECT MAX(car_id) FROM Car) -- 取最新新增的车 WHERE (s.type IS NULL OR s.type = c.type) AND (s.price_max IS NULL OR c.price <= s.price_max) AND (s.color IS NULL OR s.color = c.color);
这种方式因为可以给type、price_max、color建联合索引,查询速度会比解析URL快很多,适合数据量大的场景。
注意事项
- 如果URL参数有编码(比如
color=light%20blue),需要先解码再匹配(MySQL用UNHEX(REPLACE(...)),PostgreSQL用url_decode()函数)。 - 处理参数缺失的情况:比如有些搜索可能没设置
color,这时候要默认匹配所有颜色,所以SQL中加了(LOCATE(...) = 0 OR ...)的判断。
内容的提问来源于stack exchange,提问作者Adel taf
相关产品推荐
相关产品推荐

