简体   繁体   English

使用ORDER BY时Painfull缓慢的MySQL查询(并建立索引)

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

I have been researching but unable to solve this slow ORDER by clause on aa fairly large table (500k rows). 我一直在研究,但无法在一个相当大的表(500k行)上解决此缓慢的ORDER by子句。

I have the following query: 我有以下查询:

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

It works fast (0.0007 seconds), until the ORDER BY popularity.popularity is added, and then it takes 4.7 seconds! 它的工作速度非常快(0.0007秒),直到添加ORDER BY Popularity.popularity ,然后花费4.7秒!

The popularity table does have indexes although I understand this is irrelevant for sorting. 尽管我理解这与排序无关,但流行度表确实具有索引。 I just don;t understand why this is running so slowly. 我只是不明白;为什么运行这么慢。 When I had popularity in the same table it was fast, but I have now moved it into a separate table for performance and for increased functionality. 当我在同一张表中具有很高的知名度时,它很快,但是现在我将其移到一个单独的表中,以提高性能并增强功能。

Any advice for this greatly appreciated. 任何建议对此表示赞赏。

EXPLAIN: 说明:

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   

POPULARITY TABLE INDEXES: 人气表索引:

The table has 3 columns all of which their own index (gift_id, tag_id, popularity) Tag ID is not used in this search There is also a UNIQUE index for the three columns 该表有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  

I am curious how this version of the query performs when you have the index popularity(popularity desc, gift_id) : 我很好奇这个版本的查询在索引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;

This isn't exactly the same as your query, because gifts with no popularity are not included in the result set. 这与您的查询不完全相同,因为结果集中不包含不受欢迎的礼物。 This version might convince MySQL to use the above index on popularity , with the rest of the work being done with index lookups. 这个版本可能会说服MySQL在popularity上使用上述索引,而其余的工作都是通过索引查找完成的。

EDIT: 编辑:

If you are willing to run this as two queries, you can do the above query and then: 如果愿意将此作为两个查询运行,则可以执行上述查询,然后:

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;

You could even combine these with union all . 您甚至可以将这些与union all合并。 I sort of discourage that. 我对此有些灰心。 It would probably work in practice, but there is no explicit guarantee that the results of the union all come from the first query followed by the second. 它实际上可能会起作用,但不能明确保证并集的结果union all来自第一个查询,然后是第二个查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM