问题描述
架构:
项目: id,col_a
label_project: id、label_id、project_id
我遇到的问题是,我想获取所有带有用户使用标签的项目记录,但对于某些标签,需要进行 OR 操作,
以下是查询需要执行的操作的示例:
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setHostnameVerifier(new AllowAllHostnameVerifier());
假设有 6 个标签“类型”,对于相同类型的标签,需要在它们之间进行 OR(参见查询中的第一个 where 子句),其余使用 AND(参见 where 子句的其余部分)
示例查询的问题在于,它在 QueryDSL 中的显示时间非常长,单个查询大约需要 10 秒。我读到这主要是因为查询使用了 distinct。
有谁知道一种在 QueryDSL 中编写此查询的方法并具有更好的性能?或者在 sql 中
execution.checkpointing.interval: 10000
state.backend: filesystem
state.checkpoints.dir: file:///tmp/flink-checkpoints-directory
state.savepoints.dir: file:///tmp/flink-savepoints-directory
SELECT disTINCT gd.*
FROM project p
JOIN label_project lp1 ON lp1.label_id=306
JOIN label_project lp2 ON lp2.label_id=135
JOIN label_project lp3 ON lp3.label_id=285
JOIN label_project lp4 ON lp4.label_id=173
WHERE ( lp1.project_id=p.id
OR lp2.project_id=p.id
) -- labels of lp1 and lp2 have the same type
AND lp3.project_id=p.id
AND lp4.project_id=p.id;
-- labels of (lp1,lp2),lp3 and lp4 have different types
解决方法
我不太明白你想要达到的目标,但看看这样的事情是否可行:
SELECT gd.*
FROM grid_data gd
JOIN label_grid_data AS lgd ON lgd.grid_data_id = gd.id
WHERE lgd.label_id IN (285,173,306,135)
WHERE
子句可能需要更复杂,但我怀疑您并不真正需要所有这些子查询。
另一种方法:
( SELECT grid_data_id FROM label_grid_data
WHERE label_id IN (285,173) -- "OR"
)
UNION ALL
( SELECT grid_data_id FROM label_grid_data
WHERE label_id IN (306,135)
HAVING COUNT(*) = 2 -- kludge to achieve "AND"
)
然后
SELECT gd.*
FROM ( the above union ) AS lgd
JOIN grid_data gd ON gd.id = lgd.grid_data_id
这将为您提供具有 285 或 277 或 406 和 135 的行。
然后,请提供 SHOW CREATE TABLE
,以便我们就最佳 INDEXes
提出建议。