[英]How to convert a comma separated string into a SET to use in another query in MySQL?
让我们假设我们有两个MySQL表。
主
id | master | meta
1 | 78564 | 2,3,4
2 | 89567 | 1,3
3 | 45782 | 2,1,4
和元数据
id | buyer_id | platform
1 | 25 | mobile
2 | 35 | web
3 | 25 | web
4 | 17 | api
输入主名称时,我需要获取buyer_id和平台的数组。 主列是唯一索引,元数据的id也是唯一索引。 我想要类似的东西:
SELECT buyer_id, platform FROM metadata WHERE id IN (SELECT meta FROM
master WHERE master = '89567')
上面的查询不起作用,因为子查询返回一个字符串。 我需要某种方式将该子查询结果转换为SET。 我目前正在使用PHP来做到这一点。
<?php $sql="SELECT meta FROM master WHERE master = '89567'";
$result = $connection->query($sql);
$result = $result->fetch_assoc();
$meta = $result['meta'];
$sql="SELECT buyer_id, platform FROM metadata WHERE id IN (".$meta.")";
$result = $connection->query($sql);?>
我正在获得所需的结果,但我想对其进行优化。 我希望使用子查询或JOIN在单个查询中完成全部操作。
背景故事 :我首先只使用一个表来存储所有数据。 它也被序列化了。 我没有使用任何索引,执行时间为0.290010929。
然后,我将非唯一索引用于主表的主列。 我仍然只使用一个表,执行时间为0.0186100006。
然后,我将表分成两部分,每个表都有一个唯一索引,如上所述。 我正在使用上面的PHP代码,执行时间为0.0011548995。
我敢肯定,如果您可以回答我的问题,我可以将执行时间减少到0.0005。 我这样做是针对流量非常高的RESTful API。 我想将其最佳化。 请帮我。
更新 :感谢@RiggsFolly。
我改变了桌子的结构。
主
id | master(unique index)
1 | 78564
2 | 89567
3 | 45782
和元数据
id | master_id | buyer_id | platform
1 | 2 | 25 | mobile
2 | 3 | 25 | mobile
3 | 1 | 35 | web
4 | 3 | 35 | web
5 | 1 | 25 | web
6 | 2 | 25 | web
7 | 1 | 17 | api
8 | 3 | 17 | api
master_id是非唯一索引。
现在,我的查询是
SELECT buyer_id, platform FROM metadata WHERE master_id = (SELECT id FROM master WHERE
master = '89567')
执行时间为0.00079298019。
我认为即使将字符串转换为SET,执行时间也不会减少。 但是,我仍然想知道我的问题的答案。
使用触发器保留一个预先计算的表。
create table master_metadata(
masterid bigint(10),
metaid bigint(10)
);
那么,您的查询应为:
SELECT buyer_id, platform
FROM metadata
WHERE id IN(
SELECT metaid
FROM master_metadata
WHERE masterid = '89567'
);
下面是将保留此表的代码。
drop procedure if exists sp_tr_master_insert_update;
drop trigger if exists tr_master_insert;
drop trigger if exists tr_master_update;
delimiter //
create
definer=root@localhost
procedure sp_tr_master_insert_update(
in _masterid bigint(10)
)
modifies sql data
reads sql data
begin
declare metaids varchar(255);
--
declare commapos int;
declare metaid varchar(255);
-- -------------------------------------------------------------------------
delete from master_metadata
where masterid = _masterid;
-- -------------------------------------------------------------------------
set metaids =(
select meta
from master
where master = _masterid
);
if coalesce(metaids, '') <> '' then
_split: LOOP
set commapos = locate(',', metaids);
if commapos = 0 then
insert into master_metadata
values(_masterid, metaids);
leave _split;
else
set metaid = left(metaids, commapos - 1);
set metaids = right(metaids, length(metaids) - commapos);
insert into master_metadata
values(_masterid, metaid);
end if;
END LOOP _split;
end if;
end //
CREATE DEFINER=root@localhost TRIGGER tr_master_insert
AFTER insert ON master
FOR EACH ROW
BEGIN
CALL sp_tr_master_insert_update(NEW.master);
END//
CREATE DEFINER=root@localhost TRIGGER tr_master_update
AFTER update ON master
FOR EACH ROW
BEGIN
CALL sp_tr_master_insert_update(NEW.master);
END//
delimiter ;
索引创建和其他性能调整取决于您。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.