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 不遵守此顺序。 有没有办法在一个复杂的查询中保持顺序?

另一个相关问题 - 我的一个想法是进行两个查询:

  1. “select distinct”查询 return me the order --> saved in a list "order list"
  2. 主要的“站点”查询(变得非常简单)与“where id in {“order list”}
  3. 按“订单列表”对代码中的第二个查询进行排序。

我每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然后再问一个问题。