Как улучшить MySql-запрос, который пытается найти повторяющиеся записи в большой базе данных? - PullRequest
0 голосов
/ 04 марта 2012

Мне нужно сделать запрос в большой базе данных (оповещения 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, если они пришлиболее одного раза.Я надеюсь, что все ясно!

Какие-нибудь советы или хитрости, чтобы сделать его эффективным?

Ответы [ 2 ]

1 голос
/ 04 марта 2012

Я отформатировал ваш запрос ... если мы разберем его, вы, похоже, применяете пару функций 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 ) 
        ) 

Не связывая свой подзапрос с основной таблицей, вы предположили, что ip_dst,timestamp и layer4_dport являются каждый уникальными по всей таблице, а затем пытаются найти, где маловероятное вхождение 3 независимо уникальных значений имеет дубликаты в одной строке.

Я подозреваю, что вы хотите сделать что-то вроде следующего:

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 идентичных комбинаций timestamp и layer4_dport по вашему вопросу.

Если вы хотите найти все дубликаты на уровне ip_dst, вам нужно добавить это в свой подзапрос.

1 голос
/ 04 марта 2012

Ссылка ниже может помочь вам.

Найти дубликаты записей в MySQL

Я надеюсь, что этот пост поможет вам оптимизировать ваш запрос.

...