簡體   English   中英

使用ORDER BY時Painfull緩慢的MySQL查詢(並建立索引)

[英]Painfull slow MySQL query when using ORDER BY (And indexed)

我一直在研究,但無法在一個相當大的表(500k行)上解決此緩慢的ORDER by子句。

我有以下查詢:

SELECT gifts.gift_id, gifts.gift_title, gifts.gift_price, gifts.gift_image, gifts.gift_slug
FROM gifts
LEFT JOIN tags_gifts_occasion_specific AS os ON gifts.gift_id = os.gift_id
LEFT JOIN popularity ON popularity.gift_id = gifts.gift_id
WHERE published = '1'
AND (
os.tag_id IS NULL
)
ORDER BY popularity.popularity DESC , gift_id DESC

它的工作速度非常快(0.0007秒),直到添加ORDER BY Popularity.popularity ,然后花費4.7秒!

盡管我理解這與排序無關,但流行度表確實具有索引。 我只是不明白;為什么運行這么慢。 當我在同一張表中具有很高的知名度時,它很快,但是現在我將其移到一個單獨的表中,以提高性能並增強功能。

任何建議對此表示贊賞。

說明:

1   SIMPLE  gifts   ref     index_published     index_published     1   const   494384  Using where; Using temporary; Using filesort
1   SIMPLE  os  ref     Gift ID     Gift ID     4   gifts.gift_id   1   Using where; Using index; Not exists
1   SIMPLE  popularity  ref     Unique,Index Gift ID    Unique  4   gifts.gift_id   1   

人氣表索引:

該表有3列,所有列均具有自己的索引(gift_id,tag_id,流行度)。在此搜索中未使用標簽ID。這三列也有一個UNIQUE索引

Edit    Drop Drop   Unique  BTREE   Yes No  gift_id 26019   A   No  
tag_id  26019   A   No
Edit Edit   Drop Drop   Index Gift ID   BTREE   No  No  gift_id 26019   A   No  
Edit Edit   Drop Drop   Index Tag ID    BTREE   No  No  tag_id  3   A   No  
Edit Edit   Drop Drop   Index Popularity    BTREE   No  No  popularity  351 A   No  

我很好奇這個版本的查詢在索引popularity(popularity desc, gift_id)時如何執行:

select g.gift_id, g.gift_title, g.gift_price, g.gift_image, g.gift_slug, p.popularity
from popularity p join
     gifts g
     on p.gift_id = g.gift_id
where g.published = '1' and
      not exists (select 1
                  from tags_gifts_occasion_specific tgos
                  where tgos.gift_id = p.gift_id
                 )
order by p.popularity DESC, g.gift_id DESC;

這與您的查詢不完全相同,因為結果集中不包含不受歡迎的禮物。 這個版本可能會說服MySQL在popularity上使用上述索引,而其余的工作都是通過索引查找完成的。

編輯:

如果願意將此作為兩個查詢運行,則可以執行上述查詢,然后:

select g.gift_id, g.gift_title, g.gift_price, g.gift_image, g.gift_slug
from gifts g
where g.published = '1' and
      not exists (select 1
                  from tags_gifts_occasion_specific tgos
                  where tgos.gift_id = p.gift_id
                 ) and
      not exists (select 1
                  from popularity p
                  where p.gift_id = g.gift_i
order by g.gift_id DESC;

您甚至可以將這些與union all合並。 我對此有些灰心。 它實際上可能會起作用,但不能明確保證並集的結果union all來自第一個查詢,然后是第二個查詢。

暫無
暫無

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

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