MySql简单查询性能-1m行
我目前是网站的开发者(NSFW)。我是唯一的创建者,我开始担心一个简单的查询,它是网站的核心(我绝不是DBA) 为了快速总结,它正在收集Twitch.TV聊天中的URL。它在3周内抢走了约70万辆。该网站直观地显示了最新的Imgur和Youtube视频。我有一个“links”表,其中有一个“favorites”表,我在其中存储了用户喜欢的链接(Id、LinkId、UserId) 问题是:MySql简单查询性能-1m行,mysql,Mysql,我目前是网站的开发者(NSFW)。我是唯一的创建者,我开始担心一个简单的查询,它是网站的核心(我绝不是DBA) 为了快速总结,它正在收集Twitch.TV聊天中的URL。它在3周内抢走了约70万辆。该网站直观地显示了最新的Imgur和Youtube视频。我有一个“links”表,其中有一个“favorites”表,我在其中存储了用户喜欢的链接(Id、LinkId、UserId) 问题是: SELECT Id, URL, CapturedOn, Channel,
SELECT
Id,
URL,
CapturedOn,
Channel,
(SELECT COUNT(*) FROM favourites WHERE LinkId = links.Id) AS NumFavourites, # Is this bad per row?
Type,
Data,
CapturedBy
FROM links
WHERE
Channel LIKE "%%" AND # Can sometimes be populated with a single value, e.g. "Channel like '%riotgames%'"
Type IN ('Imgur', 'YouTube') AND # Can sometimes be "Type LIKE '%Imgur%'" or "Type LIKE '%Facebook%'" - there are about 20 different types.
Deleted = 0 AND # Out of 500k rows, about 100 will be deleted.
Id > 0 AND # Will be set to a high ID after first view to only return latest rows.
Data IS NOT NULL # Exclude badly parsed links.
ORDER BY
Id DESC LIMIT 40;
下面是解释计划:
以下是关键:
PRIMARY KEY (`ID`),
KEY `idx_links_Channel` (`Channel`),
KEY `idx_links_Type` (`Type`),
KEY `idx_links_CapturedOn` (`CapturedOn`)
“Channel-LIKE”语句可以在仅为特定用户最喜爱的频道请求链接时更改。这就变成了:
Channel IN (SELECT CONCAT('#', ChannelName) FROM channelfavourites WHERE UserId = X) AND
“Favorites”表的Id、UserId、LinkId列上有一个索引
“UserId”列的“channelfavorites”上有一个索引
以下是我的问题:
SELECT l.*FROM validlinks v JOIN links l ON l.Id=v.LinkId ORDER BY Id DESC LIMIT 40
”。但这种简单的连接值得吗
如有任何意见,将不胜感激
信息
版本():5.7.10-log
索引:
创建SQL:
CREATE TABLE `links` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Type` varchar(45) DEFAULT NULL,
`URL` text,
`CapturedOn` datetime DEFAULT NULL,
`CapturedBy` text,
`Channel` varchar(100) DEFAULT NULL,
`Data` text,
`Deleted` bit(1) DEFAULT b'0',
`DonationId` varchar(100) DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `idx_links_Channel` (`Channel`),
KEY `idx_links_Type` (`Type`),
KEY `idx_links_CapturedOn` (`CapturedOn`)
) ENGINE=InnoDB AUTO_INCREMENT=756661 DEFAULT CHARSET=utf8
如果你想提高速度,你必须在这个查询中抛弃一堆垃圾 不要将内容标记为已删除,请删除它们。如果需要归档这些文件,请将它们转储到辅助表中。把他们弄到一边去 尽可能积极地清除无效数据。这消除了查询中的
notnull
等测试。您可以过滤在应用程序层中获得的任何杂散记录
不要像那样使用,它会导致大量的表扫描。而是使用全文索引。这些速度要快得多
建立一个包含所有条件的索引。尝试对其进行排序,以便第一个项目排除与后面项目相关的大部分数据
如果必须按原样编制索引:
CREATE INDEX idx_links_for_searching (Deleted, Type, id)
加上全文,你会做得更好。就像数据库上的谋杀一样。考虑全文索引。谢谢,不考虑那些。如果我可以去掉“LIKE”而只是一个“Channel='Blah'”,那会更好吗?请发布以下输出:SELECT VERSION();显示来自链接的索引;显示创建表链接;-我几乎可以肯定,您必须创建一个复合索引。MySQL使用“正常”每个查询只有一个索引Xact匹配可以被索引,它们通常非常快像
和
像
不能,MySQL必须针对每个可能匹配的行进行测试。@MeshMan-sh…-您可以看到优化器不使用新索引-(,但不要告诉他们这样做。这不是一个好主意。我会做一点事情。我会向您发送一个查询(带有子查询)并更改数据类型以加快您的请求。您只能将此查询的输出发送给我,然后将其添加到您的查询中并执行:选择…….过程分析();哎哟,现在我很尴尬。我认为按列添加索引是正确的方法。谢谢Tadman。@MeshMan一点也不麻烦。这是一件你必须进行大量实验才能理解的事情,所以请坚持下去。对大规模加载的数据库进行基准测试非常有用。