我正在编写一个查询来从另一个表中选择玩家禁令,但首先是非常缓慢的大约需要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 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"
还有一些屏幕截图显示我的意思: First Query Second Query
在屏幕截图1中,当我要求查询仅返回带有NULL的行时,您可以看到它返回了一行,其中removedon和removetype不为null。
我也担心在历史表中会有重复的steamid和ip列条目可能会使查询变慢,有没有办法让查询只选择具有唯一ip或steamid的行基于trackingid?
非常感谢任何帮助。
由于
编辑:我被帮助淹没了,感谢@maraca,@ Skorpioh和@Adam Silenko,查询时间现在不到一秒!
答案 0 :(得分:2)
并且具有更高的优先级或者...... 您需要索引表 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) )
答案 1 :(得分:1)
查询返回的行不是NULL
,因为它被解释为
(... AND ... AND ... ) OR ...
而不是... AND ... AND ( ... OR ...)
所以你需要添加一个大括号,而且不需要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"))
答案 2 :(得分:1)
这里有一个操作员优先级问题,这就是为什么它最终会导致removetype / removedon不为空的结果。
如果您检查http://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html,您会发现AND的优先级高于OR,这意味着您的查询将运行所有谓词与" AND"操作员,之后才进行OR意味着您将看到作者匹配的结果,其余的不再重要。
如果我没错,下面的内容应该正常:
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列创建覆盖索引。这将有所帮助,但由于LIKE操作非常昂贵,可能还不够。
你应该做的最后一件事是检查你是否可以改变
进入别的东西。例如,你可以消除领先的%,这样它至少可以做得更快吗?当然取决于这些列存储的内容。理由不喜欢'%[FragSleuth]重复帐户%'