我有两个相当大的表(threads
和posts
),其中包含大量的论坛帖子。我真的必须改善搜索时间。即使在COLUMN = VALUE
进行常规搜索也要花费15秒。进行LIKE
经常会使整个网站崩溃(超时)。
threads
表包含约430,000行。
posts
表包含约2,700,000行。
我需要将它们合并到查询中以获得所需的结果。
暂时不用担心网站上的搜索框。让我们从此处开始进行此查询,然后首先开始改进此查询。
SELECT p.id, t.id, t.title, t.threadstarter, t.replies, t.views, t.board, p.dateposted FROM threads t
JOIN posts p
ON t.id = p.threadid
WHERE t.title = 'sell'
GROUP BY t.id
此查询将花费大约15秒钟的时间来获取所有线程和线程标题为“卖”的帖子。我将如何改善它,使其仅需一两秒?在具有这些大小的两个表中使用MySQL甚至可以做到吗?
然后,我将必须制作一个LIKE
(除非有另一种方法)。因为网站上的用户很可能不会搜索完全匹配的内容。而且我想添加任何包含世界“出售”的标题。这样就可以了:
SELECT p.id, t.id, t.title, t.threadstarter, t.replies, t.views, t.board, p.dateposted FROM threads t
JOIN posts p
ON t.id = p.threadid
WHERE t.title LIKE '%sell%'
GROUP BY t.id
我什至不去测量。网站崩溃(执行时间太长)。因此,这个真的(!)需要改进。
我该如何处理?我什至应该使用MySQL吗?我有什么选择?我不希望用户坐下来等待30-300秒才能完成查询。最多5秒。
用这么大的桌子有可能吗? 我听说使用“ MATCH”和“ AGAINST”可能比“ COLUMN”之类的“ VALUE”更好。但是然后我需要使所有列成为自由文本。这样做有什么缺点?
如果有人在使用大约300万行MySQL数据库,那么请告诉我您的处理方式(如果您这样做的话)。
答案 0 :(得分:0)
使用INDEX
。只需尝试在具有更多记录或主表的表之一上创建索引,尽管其内部联接仍然会使内部联接两者更容易。
此外,我只是简单地了解了group by
的用法,没有像查询中的select *..
那样聚合。
CREATE INDEX Index_NAME ON
threads(title);
答案 1 :(得分:0)
表达第一个查询的正确方法是:
SELECT p.id, t.id, t.title, t.threadstarter, t.replies, t.views, t.board, p.dateposted
FROM threads t JOIN
posts p
ON t.id = p.threadid
WHERE t.title = 'sell' AND
p.dateposted = (SELECT MIN(p2.dateposted) FROM posts p2 WHERE p2.threadid = p.threadid);
这消除了GROUP BY
,因此可以提高性能。特别是,您希望在以下位置建立索引:
threads(title, id)
posts(threadid, dateposted)
答案 2 :(得分:0)
答案 3 :(得分:0)
LIKE
(带有前导通配符)必须扫描所有430,000行:
WHERE t.title LIKE '%sell%'
更改为此:
WHERE MATCH(t.title) AGAINST('+sell' IN BOOLEAN MODE)
并拥有
FULLTEXT(title)
通过该设置,查询可以直接转到其中有'word'sell
的几行。
注意:FULLTEXT
可以搜索的内容受到限制-仅“单词”,不包括“停用词”,仅具有一定最小长度的单词,等等。