MySQL查询返回无效行,速度非常慢
我正在编写一个查询,从另一个表中选择player bans,但首先非常慢,大约需要7-14秒,其次返回无效行 第一个查询如下:MySQL查询返回无效行,速度非常慢,mysql,sql,performance,Mysql,Sql,Performance,我正在编写一个查询,从另一个表中选择player bans,但首先非常慢,大约需要7-14秒,其次返回无效行 第一个查询如下: SELECT * FROM sourcebans.sb_bans WHERE removetype IS NULL AND removedon IS NULL AND reason NOT LIKE '%[FragSleuth] Duplicate account%' AND ip IN(SELECT DISTINCT
SELECT *
FROM sourcebans.sb_bans
WHERE removetype IS NULL
AND removedon IS NULL
AND reason NOT LIKE '%[FragSleuth] Duplicate account%'
AND ip IN(SELECT DISTINCT ip
FROM fragsleuth.history
WHERE trackingid = "ad000c3803b48190aabf382e01b957c9")
OR authid IN(SELECT DISTINCT steamid
FROM fragsleuth.history
WHERE trackingid = "ad000c3803b48190aabf382e01b957c9")
第二个查询如下
SELECT * FROM `history` WHERE trackingid = "ad000c3803b48190aabf382e01b957c9"
还有几个屏幕截图来说明我的意思:
在屏幕截图1中,您可以看到,当我要求查询只返回带有null的行时,它返回了一行,其中removedon和removetype不为null
我还担心在历史记录表中,streamid和ip列会有重复的条目,这可能会使查询速度变慢。有没有办法使查询仅根据trackingid选择具有唯一ip或streamid的行
任何帮助都将不胜感激
谢谢
编辑:由于@maraca、@Skorpioh和@Adam Silenko的帮助,我被淹没了,查询时间现在不到一秒钟 查询返回的行不是
NULL
,因为它被解释为(…和…和…)或…
,而不是。。。而且。。。和(…或…)
因此,您需要添加大括号,也不需要使用DISTINCT
:
SELECT *
FROM sourcebans.sb_bans
WHERE removetype IS NULL
AND removedon IS NULL
AND reason NOT LIKE '%[FragSleuth] Duplicate account%'
AND (ip IN(SELECT ip
FROM fragsleuth.history
WHERE trackingid = "ad000c3803b48190aabf382e01b957c9")
OR authid IN(SELECT steamid
FROM fragsleuth.history
WHERE trackingid = "ad000c3803b48190aabf382e01b957c9"))
和的优先级高于或。。。 你需要在你的表上建立索引 NP如果没有,请将索引添加到fragsleuth.history中的trackingid字段 使用一个子查询可能会更快,但我不确定这一点
SELECT *
FROM sourcebans.sb_bans
WHERE removetype IS NULL
AND removedon IS NULL
AND reason NOT LIKE '%[FragSleuth] Duplicate account%'
AND exists (
SELECT 1 from fragsleuth.history
WHERE trackingid = "ad000c3803b48190aabf382e01b957c9"
and (ip = sourcebans.ip or steamid = sourcebans.authid) )
这里有一个operatior Prevendence问题,这就是为什么它最终会产生removetype/removedon不为null的结果 如果您选中该选项,您将看到它的优先级高于或意味着您的查询将运行所有用“AND”运算符粘在一起的谓词,并且仅在之后执行或意味着您将看到结果,其中authorid是匹配的,其余的不再重要 如果我没有错,下面的代码应该可以正常工作:
SELECT *
FROM sourcebans.sb_bans
WHERE removetype IS NULL
AND removedon IS NULL
AND reason NOT LIKE '%[FragSleuth] Duplicate account%'
AND
(
ip IN (SELECT DISTINCT ip
FROM fragsleuth.history
WHERE trackingid = "ad000c3803b48190aabf382e01b957c9")
OR
authid IN(SELECT DISTINCT steamid
FROM fragsleuth.history
WHERE trackingid = "ad000c3803b48190aabf382e01b957c9")
)
关于速度改进,您应该首先为removetype、removedon、ip和authid列创建覆盖索引。这将有所帮助,但可能还不够,因为类似的操作非常昂贵
你应该做的最后一件事是检查你是否可以改变
原因与“%[FragSleuth]重复帐户%不同”
变成别的东西。例如,您是否可以消除前导的%以便它至少可以进行更快的匹配?当然,这取决于这些列存储的具体内容。而且您可能需要在
ip
之前使用(
),最后使用)
。谢谢,这就解决了问题!但是现在有没有办法让查询更快?@SM9不客气。您可以分析查询并为重要列编制索引。或者如果你做不到这一点,你可以试着在where中重新排序条件,这有时会有帮助。@SM9。您可以问另一个有关加快查询速度的问题。原因是这样附加的:\“[FragSleuth]重复帐户(名称:%s)(AuthId:%s)(原因:%s)\”,因此我不确定是否有更好的方法。如果要筛选的原因总是以“[FragSleuth]重复帐户”开头,那么您可以通过将其更改为”来改善这一点原因与“[FragSleuth]Duplicate account%”不同(请注意,前导的%已被删除)。这将大大加快类似操作的速度。啊,好的,我会这样做,编辑:哇,我这样做了,我也做了@Adam Silenko说的,查询时间减少了7秒到0.0397秒,非常感谢:)嗨,你能解释一下在trackingid上添加索引会做什么吗?谢谢如果表历史记录很大(可能是的话)并且您在子查询中有列trackingid的条件,此字段上的索引可以改进此子查询的行搜索