MySQL Spring复杂查询-排序方式及查询效率
MySQL Spring complicated query - ways to order and query efficiency
我 运行 这个复杂的查询 Spring JPA 存储库。
我的目标是从站点 table 获取所有信息,并按每个站点上的事件严重性排序。
这是我的查询:
SELECT alls.* FROM sites AS alls JOIN
(
SELECT distinct ets.id FROM
(
SELECT s.id, et.`type`, et.severity_level, COUNT(et.`type`) FROM sites AS s
JOIN users_sites AS us ON (s.id=us.site_id)
JOIN users AS u ON (us.user_id=u.user_id)
JOIN areas AS a ON (s.id=a.site_id)
JOIN panels AS p ON (a.id=p.area_id)
JOIN events AS e ON (p.id=e.panel_id)
JOIN event_types AS et ON (e.event_type_id=et.id)
WHERE u.user_id="98765432-123a-1a23-123b-11a1111b2cd3"
GROUP BY s.id , et.`type`, et.severity_level
ORDER BY et.severity_level, COUNT(et.`type`) DESC
) AS ets
) as etsd ON alls.id = etsd.id
第二个 select(带有“distinct”的)returns site_ids 按严重性正确排序。
请注意,每个站点都有不同的 event_types + 严重性,我在答案上使用分页,所以我需要不同的。
问题是 - 主要 select 不遵守此顺序。
有没有办法在一个复杂的查询中保持顺序?
另一个相关问题 - 我的一个想法是进行两个查询:
- “select distinct”查询 return me the order --> saved in a list "order list"
- 主要的“站点”查询(变得非常简单)与“where id in {“order list”}
- 按“订单列表”对代码中的第二个查询进行排序。
我每10秒使用一次查询,所以它对性能非常敏感。
在这种情况下,什么似乎更快 - 原始的复杂查询还是那些 2?
任何见解将不胜感激。
非常感谢。
SQL 面向过程程序员的声明性面向集语法的一个怪癖:子查询中的 ORDER by 子句不会传递到外部查询,除非有时是偶然的。如果您想在任何查询级别进行排序,则必须在该级别指定它,否则您将得到不可预知的结果。查询优化器通常足够聪明,可以避免浪费排序操作。
您的要求:每个 sites.id
值最多给出一个 sites
行,按最坏事件排序。最差:最低事件严重性,如果有不止一个事件具有最低严重性,则计数最大。
使用这种方法为每个 id 获取“最差”,而不是 DISTINCT。
SELECT id, MIN(severity_level) severity_level, MAX(num) num
FROM (
/* your inner query */
) ets
GROUP BY id
每个 sites.id
值最多给出一行。那么你的外部查询是
SELECT alls.*
FROM sites alls
JOIN (
SELECT id, MIN(severity_level) severity_level, MAX(num) num
FROM (
/* your inner query */
) ets
GROUP BY id
) worstevents ON alls.id = worstevents.id
ORDER BY worstevents.severity_level, worstevents.num DESC, alls.id
综合起来:
SELECT alls.*
FROM sites alls
JOIN (
SELECT id, MIN(severity_level) severity_level, MAX(num) num
FROM (
SELECT s.id, et.severity_level, COUNT(et.`type`) num
FROM sites AS s
JOIN users_sites AS us ON (s.id=us.site_id)
JOIN users AS u ON (us.user_id=u.user_id)
JOIN areas AS a ON (s.id=a.site_id)
JOIN panels AS p ON (a.id=p.area_id)
JOIN events AS e ON (p.id=e.panel_id)
JOIN event_types AS et ON (e.event_type_id=et.id)
WHERE u.user_id="98765432-123a-1a23-123b-11a1111b2cd3"
GROUP BY s.id , et.`type`, et.severity_level
) ets
GROUP BY id
) worstevents ON alls.id = worstevents.id
ORDER BY worstevents.severity_level, worstevents.num DESC, alls.id
users.user_id
上的索引将有助于提高这些单用户查询的性能。
如果您仍然遇到性能问题,please read this然后再问一个问题。
我 运行 这个复杂的查询 Spring JPA 存储库。
我的目标是从站点 table 获取所有信息,并按每个站点上的事件严重性排序。
这是我的查询:
SELECT alls.* FROM sites AS alls JOIN
(
SELECT distinct ets.id FROM
(
SELECT s.id, et.`type`, et.severity_level, COUNT(et.`type`) FROM sites AS s
JOIN users_sites AS us ON (s.id=us.site_id)
JOIN users AS u ON (us.user_id=u.user_id)
JOIN areas AS a ON (s.id=a.site_id)
JOIN panels AS p ON (a.id=p.area_id)
JOIN events AS e ON (p.id=e.panel_id)
JOIN event_types AS et ON (e.event_type_id=et.id)
WHERE u.user_id="98765432-123a-1a23-123b-11a1111b2cd3"
GROUP BY s.id , et.`type`, et.severity_level
ORDER BY et.severity_level, COUNT(et.`type`) DESC
) AS ets
) as etsd ON alls.id = etsd.id
第二个 select(带有“distinct”的)returns site_ids 按严重性正确排序。 请注意,每个站点都有不同的 event_types + 严重性,我在答案上使用分页,所以我需要不同的。
问题是 - 主要 select 不遵守此顺序。 有没有办法在一个复杂的查询中保持顺序?
另一个相关问题 - 我的一个想法是进行两个查询:
- “select distinct”查询 return me the order --> saved in a list "order list"
- 主要的“站点”查询(变得非常简单)与“where id in {“order list”}
- 按“订单列表”对代码中的第二个查询进行排序。
我每10秒使用一次查询,所以它对性能非常敏感。 在这种情况下,什么似乎更快 - 原始的复杂查询还是那些 2?
任何见解将不胜感激。 非常感谢。
SQL 面向过程程序员的声明性面向集语法的一个怪癖:子查询中的 ORDER by 子句不会传递到外部查询,除非有时是偶然的。如果您想在任何查询级别进行排序,则必须在该级别指定它,否则您将得到不可预知的结果。查询优化器通常足够聪明,可以避免浪费排序操作。
您的要求:每个 sites.id
值最多给出一个 sites
行,按最坏事件排序。最差:最低事件严重性,如果有不止一个事件具有最低严重性,则计数最大。
使用这种方法为每个 id 获取“最差”,而不是 DISTINCT。
SELECT id, MIN(severity_level) severity_level, MAX(num) num
FROM (
/* your inner query */
) ets
GROUP BY id
每个 sites.id
值最多给出一行。那么你的外部查询是
SELECT alls.*
FROM sites alls
JOIN (
SELECT id, MIN(severity_level) severity_level, MAX(num) num
FROM (
/* your inner query */
) ets
GROUP BY id
) worstevents ON alls.id = worstevents.id
ORDER BY worstevents.severity_level, worstevents.num DESC, alls.id
综合起来:
SELECT alls.*
FROM sites alls
JOIN (
SELECT id, MIN(severity_level) severity_level, MAX(num) num
FROM (
SELECT s.id, et.severity_level, COUNT(et.`type`) num
FROM sites AS s
JOIN users_sites AS us ON (s.id=us.site_id)
JOIN users AS u ON (us.user_id=u.user_id)
JOIN areas AS a ON (s.id=a.site_id)
JOIN panels AS p ON (a.id=p.area_id)
JOIN events AS e ON (p.id=e.panel_id)
JOIN event_types AS et ON (e.event_type_id=et.id)
WHERE u.user_id="98765432-123a-1a23-123b-11a1111b2cd3"
GROUP BY s.id , et.`type`, et.severity_level
) ets
GROUP BY id
) worstevents ON alls.id = worstevents.id
ORDER BY worstevents.severity_level, worstevents.num DESC, alls.id
users.user_id
上的索引将有助于提高这些单用户查询的性能。
如果您仍然遇到性能问题,please read this然后再问一个问题。