MySQL查询优化需要
我有这个users
表:MySQL查询优化需要
id : int (255)
name: char (100)
last_comment_target: int(100)
last_comment_date: datetime
此表有大约1.3mil行。
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秒钟。我想知道是否有更好的方法来优化这个查询。或者,如果这个查询可以被重写。
非常感谢您的帮助。
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;
谢谢。我想知道你能否帮助我解释一下你的答案。为什么我们使用'SELECT 1 id UNION ALL SELECT 2 id UNION ALL ....'作为'JOIN'的一部分?我们真的可以在我们从另一个表派生的表上做一个'JOIN'吗?它会有什么不同(如果有的话)? –
@Heru这将创建一个所有ID的临时表。连接表通常是一个更快的解决方案,但它取决于很多因素,你应该测试它。如果你有一些其他表中的所有ID,那么你可以使用你的其他表,而不是这些UNION:'select id from other_table' – Karolis
谢谢@Karolis - 我相信内部连接更好。 –
谢谢大家的贡献。
@Karolis似乎替代使用join
代替range
所以,基本上指出:
SELECT * FROM users WHERE id IN (1,2,3,...[5000 ids]) AND last_comment_target > 0
单产EXPLAIN
声明RANGE
的type
。 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秒左右。
所以,教训从我结束了解到:TRY使用JOIN
而不是RANGE
如果你有,你可以从派生表。
你从哪里得到5000个ID? – Jacob
5000个ID来自哪里?如果你可以把它们放到一个表格中(或者它们已经在表格中)并且进行连接,它可能会更快。更好的是,如果5000个ID可以与用户中的属性相关联,那么您可以将其指定为简单条件 - 如果需要,甚至可以对其进行索引。 –
这5000个ID是手动插入还是可以查询? – AJC