MySQL 在“WHERE”中连接多个范围条款

发布于 2024-11-05 18:45:59 字数 989 浏览 0 评论 0原文

我正在尝试使用 snort 的架构并提取与我的程序相关的信息。 我使用以下查询来提取给定 IP 集在指定时间段内发生的警报。该查询类似于“

select event.sid,event.cid,event.signature,event.timestamp,iphdr.ip_proto,iphdr.ip_src,iphdr.ip_dst from 
event join iphdr 
where event.sid=iphdr.sid and event.cid=iphdr.cid and iphdr.ip_dst >= inet_aton('x.x.x.1') and iphdr.ip_dst <= inet_aton('x.x.x.255') 
or iphdr.ip_dst >= inet_aton('x.x.y.1') and iphdr.ip_dst <= inet_aton('x.x.y.255') 
and event.timestamp > "2011-05-06 00:00:00" order by timestamp 

我需要获取两个在指定时间(2011 年 5 月 6 日)之后发生的警报” IP 组(xxx0/24 和 xxy0/24)

仅对一组 IP(例如 192.168.1.0/24)(即 192.168.1.1 和 192.168.1.255 之间)执行查询既快速又简单

如果有WHERE 子句中有多个范围。例如,192.168.1.1 和 192.168.1.255 之间或 10.21.18.1 和 10.21.18.255 之间的 IP。正如上面的查询中给出的

,在这种情况下,mysql查询的执行需要很长时间才能执行(我运行了30分钟,然后不得不杀死MySQL守护进程)

我确信是OR部分导致了问题,但是不知道如何纠正它。

event 和 iphdr 表都有大约。总共 150,000 行

由于在我的程序中,用户可以指定他想要查看警报的多个子网,因此我需要无缝运行查询,而不管 WHERE 子句中的范围数量如何。

I am trying to use snort's schema and extract information relevant to my program.
I use the following query to extract alerts that have happened over a specified period of time for a given set of IPs.The query is something like

select event.sid,event.cid,event.signature,event.timestamp,iphdr.ip_proto,iphdr.ip_src,iphdr.ip_dst from 
event join iphdr 
where event.sid=iphdr.sid and event.cid=iphdr.cid and iphdr.ip_dst >= inet_aton('x.x.x.1') and iphdr.ip_dst <= inet_aton('x.x.x.255') 
or iphdr.ip_dst >= inet_aton('x.x.y.1') and iphdr.ip_dst <= inet_aton('x.x.y.255') 
and event.timestamp > "2011-05-06 00:00:00" order by timestamp 

Where I need to get the alerts that occur after specified time (06-May-2011) for two sets of IPs (x.x.x.0/24 and x.x.y.0/24)

Execution of the query for ONLY ONE set of IPs (say 192.168.1.0/24) (i.e. between 192.168.1.1 and 192.168.1.255) is fast and easy

The problem happens if there are multiple ranges in WHERE clause. E.g. IPs between 192.168.1.1 and 192.168.1.255 OR between 10.21.18.1 and 10.21.18.255. As given in query above

In such a case, the execution of the mysql query takes long time to execute (I ran it for 30 minutes and then had to kill MySQL daemon)

I am sure it is the OR part that is causing the problem but don't know how to rectify it.

Both the event and iphdr tables have approx. 150,000 rows in all

Since in my program the user may specify multiple subnets for which he wants to see the alerts, I need the query to run seamlessly irrespective of the number of ranges in WHERE clause.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久夏青 2024-11-12 18:45:59

SQL 中,AND 的优先级高于OR

您的过滤器实际上是这样的:

(
event.sid=iphdr.sid and event.cid=iphdr.cid and iphdr.ip_dst >= inet_aton('x.x.x.1') and iphdr.ip_dst <= inet_aton('x.x.x.255')
)
or
(
iphdr.ip_dst >= inet_aton('x.x.y.1') and iphdr.ip_dst <= inet_aton('x.x.y.255') and event.timestamp > "2011-05-06 00:00:00"
)

第二个条件破坏了 iphdr 和 event 之间的相关性,从而导致它们子集的笛卡尔连接。

OR 子句放入括号中:

event.sid=iphdr.sid
AND event.cid=iphdr.cid
AND
(
iphdr.ip_dst BETWEEN inet_aton('x.x.x.1') AND inet_aton('x.x.x.255')
OR
iphdr.ip_dst BETWEEN inet_aton('x.x.y.1') AND inet_aton('x.x.y.255')
)
AND event.timestamp > "2011-05-06 00:00:00"

您可能还想创建这些索引:

iphdr (ip_dst)
event (timestamp)

In SQL, AND has higher precedence that OR.

Your filter is in fact this:

(
event.sid=iphdr.sid and event.cid=iphdr.cid and iphdr.ip_dst >= inet_aton('x.x.x.1') and iphdr.ip_dst <= inet_aton('x.x.x.255')
)
or
(
iphdr.ip_dst >= inet_aton('x.x.y.1') and iphdr.ip_dst <= inet_aton('x.x.y.255') and event.timestamp > "2011-05-06 00:00:00"
)

The second conditions breaks correlation between iphdr and event which results in an cartesian join of their subsets.

Put the OR clause into brackets:

event.sid=iphdr.sid
AND event.cid=iphdr.cid
AND
(
iphdr.ip_dst BETWEEN inet_aton('x.x.x.1') AND inet_aton('x.x.x.255')
OR
iphdr.ip_dst BETWEEN inet_aton('x.x.y.1') AND inet_aton('x.x.y.255')
)
AND event.timestamp > "2011-05-06 00:00:00"

You may also want to create these indexes:

iphdr (ip_dst)
event (timestamp)
生死何惧 2024-11-12 18:45:59

WHERE 中的 OR 会破坏您的连接。尝试将连接从 where 中取出,或者至少在 OR 周围使用方括号,例如:

select event.sid,event.cid,event.signature,event.timestamp,
iphdr.ip_proto,iphdr.ip_src,iphdr.ip_dst 
from event join iphdr on (event.sid=iphdr.sid and event.cid=iphdr.cid)
where iphdr.ip_dst >= inet_aton('x.x.x.1') 
and (
iphdr.ip_dst <= inet_aton('x.x.x.255') 
or iphdr.ip_dst >= inet_aton('x.x.y.1') 
)
and iphdr.ip_dst <= inet_aton('x.x.y.255') 
and event.timestamp > "2011-05-06 00:00:00" 
order by timestamp 

Your OR in the WHERE ruins your join. Try to get the join out of the where or at least use brackets around the OR, e.g.:

select event.sid,event.cid,event.signature,event.timestamp,
iphdr.ip_proto,iphdr.ip_src,iphdr.ip_dst 
from event join iphdr on (event.sid=iphdr.sid and event.cid=iphdr.cid)
where iphdr.ip_dst >= inet_aton('x.x.x.1') 
and (
iphdr.ip_dst <= inet_aton('x.x.x.255') 
or iphdr.ip_dst >= inet_aton('x.x.y.1') 
)
and iphdr.ip_dst <= inet_aton('x.x.y.255') 
and event.timestamp > "2011-05-06 00:00:00" 
order by timestamp 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文