簡體   English   中英

MySQL:如何通過2個聯接和1個子查詢提高選擇查詢的速度

[英]MySQL: how to increase speed of a select query with 2 joins and 1 subquery

在表“ ttraces”中,我有許多記錄用於不同的任務(其值保存在“ taskid”列中,並且是表“ ttasks”中列“ id”的外鍵)。 每個任務每8-10秒就會在“ ttraces”中插入一條記錄,因此緩存數據以提高性能並不是一個好主意。 我需要的是從“ ttraces”中僅選擇每個任務的最新記錄,這意味着記錄中“ time”列的最大值。 目前,表中有超過500000條記錄。 這兩個表的非常簡化的結構如下所示:

-----------------------
|       ttasks        |
-----------------------
| id | name | blocked |
-----------------------

---------------------
|      ttraces       |
---------------------
| id | taskid | time |
---------------------

我的查詢如下所示:

SELECT t.name,tr.time
FROM 
    ttraces tr 
    JOIN 
    ttasks t ON tr.itask = t.id 
    JOIN (
        SELECT taskid, MAX(time) AS max_time
        FROM ttraces 
        GROUP BY itask
    ) x ON tr.taskid = x.taskid AND tr.time = x.max_time
WHERE t.blocked

WHERE和JOIN子句中使用的所有列均已建立索引。 目前,查詢運行了大約1.5秒。 加快速度至關重要。 感謝您的所有建議。 順便說一句:該數據庫正在托管的共享服務器上運行,目前我無法將其移動到其他任何地方。

[編輯]解釋選擇...結果是:

--------------------------------------------------------------------------------------------------------------
id   select_type   table        type     possible_keys   key       key_len   ref          rows     Extra
--------------------------------------------------------------------------------------------------------------
1   PRIMARY        <derived2>   ALL      NULL            NULL      NULL      NULL         74   
1   PRIMARY        t            eq_ref   PRIMARY         PRIMARY   4         x.taskid     1        Using where
1   PRIMARY        tr           ref      taskid,time     time      9         x.max_time   1        Using where
2   DERIVED        ttraces      index    NULL            itask     5         NULL         570853   
--------------------------------------------------------------------------------------------------------------

引擎是InnoDB。

我可能需要一點時間,但是此查詢在邏輯上是不一樣的,並且(幾乎可以肯定)更快嗎?

SELECT t.id, t.name,max(tr.time)
FROM 
ttraces tr 
JOIN 
ttasks t ON tr.itask = t.id 
where BLOCKED
group by t.id, t.name

如果每個任務有很多跟蹤,那么您可以保留僅包含最新跟蹤的表。 每當您插入到ttrace中時,您也會向上插入ttraces_newest:

insert into ttraces_newest (id, taskid, time) values
(3, 1, '2012-01-01 08:02:01')
on duplicate key update
`time` = current_timestamp

ttraces_newest的主鍵是(id,taskid)。 查詢ttraces_newest會更便宜。 便宜多少取決於每個任務有多少條痕跡。 現在查詢是:

SELECT t.name,tr.time
FROM 
    ttraces_newest tr 
    JOIN 
    ttasks t ON tr.itask = t.id 
WHERE t.blocked

這是我的主意...您需要在ttraces有一個復合索引, ttraces具有taskidtime列( ttraces順序)。 比使用以下查詢:

SELECT t.name,
       trm.mtime
FROM   ttasks AS t
       JOIN (SELECT taskid,
                    Max(time) AS mtime
             FROM   ttraces
             GROUP  BY taskid) AS trm
         ON t.id = trm.taskid
WHERE  t.blocked 

此代碼返回正確的結果嗎? 如果是這樣,它的速度如何?

SELECT t.name, max_time 
FROM ttasks t JOIN ( 
    SELECT taskid, MAX(time) AS max_time 
    FROM ttraces  
    GROUP BY taskid
) x ON t.id = x.taskid

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM