0

我必须对大型数据库(Snort 警报)进行查询以查找重复条目。但是,我想出了下面的查询,但是执行起来需要很多时间!

SELECT sid, cid, timestamp, sig_name, inet_ntoa(ip_src), layer4_sport,
       inet_ntoa(ip_dst), layer4_dport
  FROM DB
 WHERE (ip_dst IN
        (SELECT ip_dst FROM DB GROUP BY ip_dst HAVING count(*) > 1)
   AND timestamp IN
        (SELECT timestamp FROM DB GROUP BY timestamp HAVING count(*) > 1)
   AND layer4_dport IN
        (SELECT layer4_dport FROM DB GROUP BY layer4_dport HAVING count(*)>1 ))

上面的查询试图查找具有相同的警报 ip_dst timestamp以及layer4_dport 它们是否出现了不止一次。我希望它清楚!

有什么提示或技巧可以提高效率吗?

4

2 回答 2

1

我已经格式化了您的查询...如果我们将其分解,您似乎正在应用几个函数inet_ntoa。如果您没有迫切的需求,请摆脱它们(尤其是当他们看桌子时)。

其次,如果我们查看您的查询,您正在DB对各种计数进行 3 次完整扫描,然后至少在您的顶级选择中进行范围扫描。

SELECT sid, cid, timestamp, sig_name, inet_ntoa(ip_src), layer4_sport, inet_ntoa(ip_dst), layer4_dport 
  FROM DB 
 WHERE ( ip_dst IN ( SELECT ip_dst 
                       FROM DB 
                      GROUP BY ip_dst 
                     HAVING count(*) > 1 ) 
   AND timestamp IN ( SELECT timestamp 
                        FROM DB 
                       GROUP BY timestamp 
                      HAVING count(*) > 1 ) 
   AND layer4_dport IN ( SELECT layer4_dport 
                           FROM DB 
                          GROUP BY layer4_dport 
                         HAVING count(*) > 1 ) 
        ) 

通过不将子查询链接回主表,您假设和在整个表中都是唯一的,然后试图找出不太可能出现的 3 个独立唯一值恰好在同一行中有重复ip_dsttimestamplayer4_dport

我怀疑您想要做的事情如下:

SELECT a.sid, a.cid, a.ip_dst, a.timestamp, a.sig_name, a.layer4_sport, a.layer4_dport 
  FROM DB a 
  JOIN ( SELECT timestamp, layer4_dport 
           FROM DB 
          GROUP BY timestamp, layer4_dport
         HAVING count(*) > 1 ) b
    ON a.timestamp = b.timestamp
   AND a.layer4_dport = b.layer4_dport

根据您的问题,这将为您找到超过 1 个相同timestamplayer4_dport组合的所有行。

如果要查找级别的所有重复项,ip_dst则需要将其添加到子查询中。

于 2012-03-04T09:46:06.100 回答
1

下面的链接可以帮助你。

在 MySQL 中查找重复记录

我希望这篇文章可以帮助您优化查询。

于 2012-03-04T09:14:01.010 回答