我有这个users
表格:
id : int (255)
name: char (100)
last_comment_target: int(100)
last_comment_date: datetime
此表有大约1.3万行。
PKEY
和BTREE
位于id
,last_comment_target
和last_comment_date
。
并且,我正在尝试执行范围查询:
SELECT * FROM users
WHERE id IN (1,2,3,5,...[around 5000 ids])
AND last_comment_target > 0
ORDER BY last_comment_dt DESC LIMIT 0,20;
有时查询可能需要3秒钟。我想知道是否有更好的方法来优化此查询。或者,如果可以重写此查询。
非常感谢你的帮助。
答案 0 :(得分:1)
SELECT u.*
FROM
users u
JOIN (
SELECT 1 id
UNION ALL
SELECT 2 id
UNION ALL
:
:
SELECT 5000 id
) ids ON ids.id = u.id
WHERE
last_comment_target > 0
ORDER BY
last_comment_dt DESC
LIMIT 0, 20;
答案 1 :(得分:0)
感谢所有贡献的人。
@Karolis似乎指出使用join
代替range
的替代方案
所以,基本上:
SELECT * FROM users WHERE id IN (1,2,3,...[5000 ids]) AND last_comment_target > 0
在EXPLAIN
语句中产生type
RANGE
。可以从另一个表生成5000个ID。
当我将上述内容切换为:
SELECT *
FROM users u
INNER JOIN user_friends uf ON u.id = uf.to_id
AND u.last_comment_target > 0
AND uf.from_id = [id];
它会在EXPLAIN
语句中产生两个types
:ref
和eq_ref
,这比此查询中的range
更快。
查询执行时间从3秒减少到大约0.2x秒。
所以,从我的结论中吸取教训:尝试使用JOIN
代替RANGE
,如果你有一个可以派生的表。