DNSBL
Потребовалось проверить некий IP адрес на наличие в блеклистах. Обычно для проверки занесен ли адрес в блеклист используют класс pear Net_DNSBL но у меня локально он наотрез отказался работать корректно, к тому же он требует чтобы PHP был не ниже 5.3.x.x. Такое его поведение мне не понравилось, поэтому решил разобраться как на самом деле происходит проверка. Оказалось все банально до пошлости: сам блеклист есть не что иное как набор DNS файлов на некоем сервере. Допустим, нужно проверить есть ли IP 1.2.3.4 на блеклисте 'db.wpbl.info' для этого просто достаточно проверить существует ли субдомен: 4.3.2.1.db.wpbl.info (обратите внимание - IP указывается в обратном порядке). Если существует - адрес в блеклисте, если нет - на нет и суда нет. Функция checkdnsrr нам в помощь.
По аналогии с http://www.dnsbl.info/dnsbl-database-check.php сделал аналогичный сервис у себя на сайте - на всякий случай.
Кстати, оказалось что ренетовский IP через который я выхожу в Internet находится сразу в нескольких блеклистах из этого списка.
Не все индексы одинаково полезны
Имеется InnoDB табличка, небольшая - меньше миллиона записей, делаем такой запрос (нужно получить top10 доменов):
> select dlvDestinationDomain, count(*) from email_accounting where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10
созданы следующие индексы:
| PRIMARY | BTREE | id |
|---|---|---|
| jobId | BTREE | jobId |
| dlvDestinationDomain | BTREE | dlvDestinationDomain |
| dlvDestinationDomain_2 | BTREE | dlvDestinationDomain |
| A | ||
| jobId_3 | BTREE | jobId |
| A |
Обнаружилась забавная вещь: некоторые индексы не только не ускоряют но и замедляют агрегатные запросы:
вообще без использования индексов:
mysql> select dlvDestinationDomain, count(*) from email_accounting IGNORE INDEX(dlvDestinationDomain_2, jobId_3, jobId, dlvDestinationDomain) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;
3.09 секунды
используя индекс по jobId дает небольшой прирост производительности:
mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (jobId) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;
2.13 секунд;
использование составного индекса по jobID и dlvDestinationDomain сделало все гораздо веселее:
mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (jobId_3) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;
0.39 секунд;
ипользование ключа с полям в обратном порядке (dlvDestinationDomain и jobID) работает гораздо хуже:
mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (dlvDestinationDomain_2) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;
1.36 секунд;
А вот использование ключа только по dlvDestinationDomain заставляет MySQL думать почти две минуты:
mysql> select dlvDestinationDomain, count(*) from email_accounting FORCE INDEX (dlvDestinationDomain) where jobid="11837" group by dlvDestinationDomain order by count(*) desc limit 10;
1 минута 48 секунд;
Кстати, заметил, что использование jobid="11837" (jobid у меня текстовое) заметно прибавляет скорости против jobid=11837. Не зря в strict моде MySQL грязно ругается на такие преобразования, ох не зря...
Upd. Во всем оказались замешаны настройки InnoDB, если увеличить в my.cnf значение переменной innodb_buffer_pool_size то скорость выполнения агрегативного запроса с индексом по группируемому полю заметно возрастает и картина меняется на прямо противоположную.
О свободе слова в Интернет
Вчера рассказали изумительный стишок:
Товарищ верь, пройдет она,
И демократия и гласность,
Но Комитет Госбезопасность,
Запомнит ваши имена!
Покатался с горки
Сегодня сходил покатался с горки на Первой Дачной, всего за этот год это получился уже четвертый раз когда я выбрался покататься. Катался на горнолыжной базе "Роща".
В прошлые разы немного поснимал телефоном, и наконец, смонтировал то что получилось: