如何通过大的IN列表,大LIMIT偏移和ORDER BY来提高MySQL查询速度

时间:2014-03-12 18:16:25

标签: mysql sql optimization

SELECT 
mp_library.`lid` AS itemId, 
mp_library.`cid` AS itemCategory, 
mp_library.`photo` AS itemPhoto, 
mpl_names.`name` AS itemName, 
mp_users.`uid` AS userId 
FROM mvc_public_library AS mp_library 
INNER JOIN mvc_public_library_names AS mpl_names ON mpl_names.lid = mp_library.lid 
LEFT JOIN mvc_public_wishlist AS mp_wishlist ON mp_wishlist.lid = mp_library.lid AND 
          mp_wishlist.uid = 31 AND mp_wishlist.status = "1" 
LEFT JOIN mvc_public_users AS mp_users ON mp_users.uid = mp_wishlist.uid AND 
          mp_users. STATUS = "2" 
WHERE 
      mp_library.status = "1" AND 
      mpl_names.language = "en" AND 
      mp_library.cid IN (3, 9967, 4, 20, 5, 9950, 6, 9971, 7, 9979, 12, 271, 272, 13, 2502, 2503, 15, 9925, 630, 778, ... , 3184 ) 
ORDER BY mp_library.lid DESC 
LIMIT 268320, 48

上面的查询在IN(...)部分中有1000到3000个ID。

EXPLAIN语句输出:enter image description here

在所有已连接的表中,我设置了索引。 查询的持续时间约为8秒,这是一个很长的时间。 如果我消除了JOINS并仅运行SELECT * FROM mvc_public_library WHERE cid IN (...),则查询需要3秒钟,同样需要很长时间。

您有什么建议可以减少查询时间吗?我在其他帖子中注意到大的IN列表是一个问题,大的LIMIT偏移是一个问题,ORDER BY是一个问题,这里我全部3:)

@LATER EDIT

我设法将查询减少到此(没有列表):

SELECT mp_library.`lid` AS itemId,mp_library.`cid` AS itemCategory,mp_library.`photo` AS itemPhoto,mpl_names.`name` AS itemName,mp_users.`uid` AS userId 
FROM mvc_public_library AS mp_library 
INNER JOIN mvc_public_library_names AS mpl_names ON mpl_names.lid = mp_library.lid 
LEFT JOIN mvc_public_wishlist AS mp_wishlist ON mp_wishlist.lid = mp_library.lid AND 
          mp_wishlist.uid = 31 AND 
          mp_wishlist.status = "1" 
LEFT JOIN mvc_public_users AS mp_users ON mp_users.uid = mp_wishlist.uid AND 
          mp_users.status = "2" 
WHERE 1 AND mp_library.status = "1" AND 
            mpl_names.language = "ro" 
ORDER BY mp_library.lid DESC 
LIMIT 268320,48

此外,我已经添加了@DRapp建议的indeces,并从8秒到5秒进行了改进。我想知道它是否可以进一步改进。以下是新查询的解释声明:enter image description here

2 个答案:

答案 0 :(得分:1)

我怀疑问题的关键是你需要mp_library(status, cid)上的索引。实际上,以下索引将涵盖查询:

create index on mp_library(status, cid, lid, photo)

答案 1 :(得分:1)

我会在所有表格上覆盖索引,例如

table                     index
mvc_public_library        ( status, cid, lid, photo )
mvc_public_library_names  ( lid, language, `name` )
mvc_public_wishlist       ( lid, uid, status )
mvc_public_users          ( udi, status )

另外,我稍微改写了,如果1秒的改进不是更好,我会添加关键字

SELECT STRAIGHT_JOIN ... rest of your query.