[英]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.