2015-11-03 64 views
0

我有一个作业队列,它是FIFO,可以增长到0到10MM范围的记录。每条记录都有一些与用户相关的价值。我有第二个表可以包含具有优先级的USERS。这被工作线程查询了很多。当按此优先级排序时,这会导致1MM记录范围内的查询缓慢,例如,MariaDB简单加入无临时表的订单

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

你想要返回所有10MM行吗?也许应该有一个“限制”? –

回答

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

+0

我最终做了计划B,但我想知道我是否可以测试计划A. – jbh