MariaDB 简单加入 order by 没有临时 table

MariaDB simple join with order by without temp table

我有一个先进先出的作业队列,可以增长到 0 到 10MM 记录的范围。每条记录都有一些与用户相关的值。我有第二个 table 可以包含具有优先权的用户。这会被工作线程查询很多。当按此优先级排序时,这会导致 1MM 记录范围内的查询变慢,例如

select  *
    from  calcqueue
    LEFT JOIN  calc_priority USING(userId)
    where  calcqueue.isProcessing IS NULL
    order by  ISNULL(calc_priority.priority), calc_priority.priority

运行 对此的解释让我“Using index condition; Using temporary; Using filesort”。我试图将其切换到派生的 table,它可以扩展更多的行,但是我无法保留保留的顺序,这违背了真正的意图(但至少让我的服务器保持快速)

SELECT  *
    FROM  
      ( SELECT  priority,p,userId FROM
              ( SELECT  calc_priority.priority,
                        qt_uncalc.userId,
                        ISNULL(calc_priority.priority) p
                    from  
                      ( SELECT  userId
                            from  calcqueue
                            WHERE  isProcessing IS NULL
                      ) qt_uncalc
                    LEFT JOIN  calc_priority USING(userId) sortedQ
                    ORDER BY  p,sortedQ.priority ASC
              ) orderedT 

有没有办法仅使用派生的 table 来实现这一点? calc_priority 可以(并且确实)改变很多。所以在 calcqueue 插入时添加优先级不是一个选项

计划A

咀嚼这个:

      ( SELECT  *, 999999 AS priority
            from  calcqueue
            LEFT JOIN  calc_priority USING(userId)
            where  calcqueue.isProcessing IS NULL
              AND  calc_priority.priority IS NULL
            LIMIT  10 
      )
    UNION  ALL
      ( SELECT  *, calc_priority.priority
            from  calcqueue
            JOIN  calc_priority USING(userId)
            where  calcqueue.isProcessing IS NULL
            ORDER BY  calc_priority.priority
            LIMIT  10 
      )
    ORDER BY  priority

并包括

    LIMIT  10; INDEX(isProcessing, userId)

我试图避免 NULL 的麻烦。

B计划

您可以将应用更改为始终将 priority 设置为合适的值,从而避免必须执行 UNION.