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
.
我有一个先进先出的作业队列,可以增长到 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
.