我有一个FIFO作业队列,可以增长到0到10MM的记录范围。每条记录都有一些与用户相关的值。我有一个第二个表,可以包含优先级的USERS。工作线程会对此进行大量查询。当按此优先级排序时,这会导致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
"。我试图将其切换到派生表,该表可以扩展到更大的行数,但是我无法保持保留的顺序,这会破坏真正的意图(但至少可以使我的服务器保持快速)
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
无论如何只能使用派生表来实现这一目标吗? calc_priority可以(并确实)改变很多。因此,在calcqueue插入时添加优先级不是一个选项
答案 0 :(得分:1)
计划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
。