优化 100 万行的查询
Posted
技术标签:
【中文标题】优化 100 万行的查询【英文标题】:Optimising a Query with 1 million rows 【发布时间】:2020-11-21 14:15:18 【问题描述】:我一直在尝试优化我得到的这个查询,最初我对 vip.tvip 数据库使用 INNER JOIN 但注意到该表中不存在的人没有显示和阅读我必须使用导致更多问题的 LEFT JOIN。
SELECT sb_admins.srv_group AS role, rankme.lastconnect, rankme.steam, rankme.name, rankme.pfp, vip.tvip.vip_level FROM bans.sb_admins
INNER JOIN rankme ON CONCAT("STEAM_0:", rankme.authid) = sb_admins.authid
LEFT JOIN vip.tvip ON tvip.playerid = rankme.authid
AND gid > 0 ORDER BY rankme.name;
这是我目前正在使用的查询,由于 rankme 表有 130 万行,它似乎需要大约 5 秒才能得到结果。我也附上了这个查询的解释,我对 mysql 查询不是很精通,所以如果我把这个宰了,我很抱歉。
如果有人能提供有关如何解决此问题的见解,那将非常有帮助。我已经为我可以创建的任何内容创建了密钥,例如名称为 FULLTEXT 密钥等,但仍然没有占上风。
干杯。
【问题讨论】:
我可以看到您的加入条件之一是使用CONCAT
。这将使该连接成为非 sargable,这意味着 MySQL 将无法使用任何索引来优化该特定连接。考虑修复您的数据模型,以便您可以直接加入列,而无需使用CONCAT
。
谢谢蒂姆 - 不知道。不幸的是,由于 Steam 呈现其 Steam ID 的方式,CS:GO 引擎使用新宇宙,而旧软件使用旧宇宙,因此出现 STEAM_1 和 STEAM_0 问题。
gid
属于哪个表? gid > 0
将您的结果缩小了多少? IE。此查询返回的行的百分比是多少? 99%? 1%?较少的?这些表是如何关联的? authid
在一个或多个表中是唯一的吗?您在同一个 ID 上加入所有三个表似乎很奇怪。因此,您可能会产生不想要的笛卡尔积。
sb_admins.gid 是它的来源,它基本上是员工的组 ID。只有大约 10-20 人会拥有它。
gid
在什么表???请提供SHOW CREATE TABLE
。
【参考方案1】:
你可以试试:
SELECT sb_admins.srv_group AS role, rankme.lastconnect, rankme.steam, rankme.name, rankme.pfp, vip.tvip.vip_level FROM bans.sb_admins
INNER JOIN rankme ON rankme.authid = REPLACE(sb_admins.authid,"STEAM_0:","")
LEFT JOIN vip.tvip ON tvip.playerid = rankme.authid
AND gid > 0 ORDER BY rankme.name;
这应该可以在rankme中使用rankme.authid
上的索引。 (如果存在的话……)
【讨论】:
速度是多少? “另一个”大约是 5 秒,而这个呢? (只是好奇)? 一秒钟也没有 ?以上是关于优化 100 万行的查询的主要内容,如果未能解决你的问题,请参考以下文章
PHP PDO 查询,优化超过 1000 万行的速度性能 MS ACCESS 数据库