Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737 Форумы портала PHP.SU :: Помогите оптимизировать таблицу
Покинул форум
Сообщений всего: 305
Дата рег-ции: Янв. 2012
Помог: 1 раз(а)
Имеется таблица: id, url, html. В url хранятся урлы вида "http://site.com/news/bla-bla-bla/bla-bla/bla". А в столбце html соответвенно html код запрашиваемого урла. Сейчас в таблице чуть более 10 000 записей, и уже сейчас выборка типа SELECT * FROM crawler WHERE url = 'http://site.com/bla-bla/bla-bla/bla'; занимает пол секунды, а т.к. этот запрос происходит при получении любого url, в целом это влияет на загрузку любой страницы (не важно со старой версии сайта она или с новой). В итоге, имею почти секундную задержку до получения контента.
но к каким либо заметным результатам это не привело. Что я делаю не так и как мне ускорить выборку по текстовому полю такой длинны какую обычно имеют современные модные многоуровневые ЧПУ УРЛы?
Заранее спасибо за идеи!
RickMan
Отправлено: 02 Сентября, 2014 - 14:35:33
Участник
Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012
Помог: 30 раз(а)
А url, я так понимаю, уникальный?
nkl
Отправлено: 02 Сентября, 2014 - 14:43:49
Посетитель
Покинул форум
Сообщений всего: 305
Дата рег-ции: Янв. 2012
Помог: 1 раз(а)
Да, url уникальный. Сейчас попробовал сделать его первичным ключом таблицы, один фиг, оно наоборот еще медленнее стало. (Добавление)
Перевел таблицу в MYISAM, сделал полнотекстовый индекс для этого поля длиной 255 символов итог: никакого прироста в скорости выборки.
RickMan
Отправлено: 02 Сентября, 2014 - 15:12:14
Участник
Покинул форум
Сообщений всего: 1033
Дата рег-ции: Май 2012
Помог: 30 раз(а)
nkl пишет:
Да, url уникальный. Сейчас попробовал сделать его первичным ключом таблицы, один фиг, оно наоборот еще медленнее стало. (Добавление)
Перевел таблицу в MYISAM, сделал полнотекстовый индекс для этого поля длиной 255 символов итог: никакого прироста в скорости выборки.
А зачем делать первичным? Пусть первичным будет id. Сделай его для начала уникальным.
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
Повесьте хэш-индекс.
Правда, mysql их не умеет, так что добавляете ещё поле и заполняете его значением хеш-функции от урла. Возможно простой int и crc32 дадут достаточную селективность. Искать надо, соответственно, по WHERE url = 'http://site.com/bla-bla/bla-bla/bla' and hash_index='значение CRC32 от урла'
----- PostgreSQL DBA
tuareg
Отправлено: 02 Сентября, 2014 - 18:51:28
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Мелкий пишет:
Искать надо, соответственно, по WHERE url = 'http://site.com/bla-bla/bla-bla/bla' and hash_index='значение CRC32 от урла'
Да только наоборот WHERE hash_index='значение CRC32 от урла' AND url = 'http://site.com/bla-bla/bla-bla/bla'
Мелкий
Отправлено: 02 Сентября, 2014 - 19:11:47
Активный участник
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
tuareg, не имеет значения. Если только для соблюдения принятого в проекте стандарта кодирования.
----- PostgreSQL DBA
nkl
Отправлено: 03 Сентября, 2014 - 10:11:49
Посетитель
Покинул форум
Сообщений всего: 305
Дата рег-ции: Янв. 2012
Помог: 1 раз(а)
В общем, сделал еще 2 поля одно с md5, а другое с crc32 хэшами урлов, прироста в скорости никакой. Стал на хостера грешить, потому как ранее с ним не работал, дампанул базу на сервер digitalocean'a где все наши проекты крутятся, один хер, скорость выборки не изменилась, прямо печалька какая-то, скорость выборки:
crc32 = Запрос открыт за 1,254c [0,385c выполнение, 0,869c выборка]
Кстати говоря, раньше быстрее было, пока еще 2 столбца не добавил, и спрашивал по текстовому полю:
Запрос открыт за 0,652[0,285 выполнение, 0,367 выполнение]
Мне бы добиться общего времени работы запроса хотя бы до 0,3 сек, было бы просто шоколадно, тогда страница отлетала бы в nginx за полсекунды, но увы и ах
Может на sql.ru что подскажут...
tuareg
Отправлено: 03 Сентября, 2014 - 10:37:36
Участник
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Добавьте еще LIMIT 1;
И выложите EXLAIN запроса
P.S я надеюсь по полям индекс есть?
Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009 Откуда: Россия, Санкт-Петербург
Помог: 618 раз(а)
tuareg пишет:
P.S я надеюсь по полям индекс есть?
Присоединяюсь к вопросу.
----- PostgreSQL DBA
nkl
Отправлено: 03 Сентября, 2014 - 10:51:24
Посетитель
Покинул форум
Сообщений всего: 305
Дата рег-ции: Янв. 2012
Помог: 1 раз(а)
Вот explain запроса:
id - 1
select_type - SIMPLE
table - crawler
type - const
possible_keys - UK_crawler_crc32_has
key - UK_crawler_crc32_has
key_len - 8
ref - const
rows - 1
Extra - null
P.S.
Если выбирать по id записи, скорость такая же, в среднем 0.8 с.
Вот как щас таблица выглядит:
Покинул форум
Сообщений всего: 1234
Дата рег-ции: Июнь 2010
Помог: 69 раз(а)
Не ускорите, если тупо запрос по id => 0.8c . Быстрей работать не будет
Т.е быстрей чем по PK никак.
P.S но это очень странно, почему так долго выполняется этот запрос
INDEX IDX_crawler (crc32_hash, id, url, visit_date),# Вот это тоже зачем???
INDEX UK_crawler_crc32_hash (crc32_hash)
)
ENGINE = INNODB
nkl
Отправлено: 03 Сентября, 2014 - 14:16:42
Посетитель
Покинул форум
Сообщений всего: 305
Дата рег-ции: Янв. 2012
Помог: 1 раз(а)
Пардоньте друзья! Все в порядке! Это оказывается мой клиент СУБД так тормозит, хотя я пользовался функцией профилировки запросов в нем. В частности клиент называется dbForge Studio fo MySQL, удобный и няшный, но тупит оказывается.
Сейчас проверил те же самые запросы через консоль и вуаля, запрос по УРЛу занимает 0,02 c., запрос по id 0,00 c., запрос по crc32 хэшу 0.00 c.
Сами полюбуйтесь:
mysql> SELECT * FROM ***.crawler WHERE id = 2145 LIMIT 1;
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
| id | url | visit_date | html | crc32_hash |
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
| 2145 | http://site[dot]com/news/chempionat_[dot][dot][dot]/2014-03-22-8846 | 0000-00-00 00:00:00 | | 3191665859 |
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
1 row in set (0,00 sec)
mysql> SELECT * FROM ***.crawler WHERE url = "http://site.com/news/chempionat_rossii_2013_14_22_j_tur_razogrev_22_03_2014/2014-03-22-8846" LIMIT 1;
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
| id | url | visit_date | html | crc32_hash |
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
| 2145 | http://site[dot]com/news/chempionat_[dot][dot][dot]/2014-03-22-8846 | 0000-00-00 00:00:00 | | 3191665859 |
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
1 row in set (0,02 sec)
mysql> SELECT * FROM ***.crawler WHERE crc32_hash = 3191665859 LIMIT 1;
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
| id | url | visit_date | html | crc32_hash |
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
| 2145 | http://site[dot]com/news/chempionat_[dot][dot][dot]/2014-03-22-8846 | 0000-00-00 00:00:00 | | 3191665859 |
+------+---------------------------------------------------------------------------------------------------+---------------------+------+------------+
1 row in set (0,00 sec)
отдельное спасибо пользователю tuareg, именно он посчитал странным столь долгую выборку по primary_key [b]id[/b].
Мораль сей басни такова, меряйте скорость выполнения запросов mysql непосредственно из консоли mysql, а не сторонним говнософтом расположенным на расстоянии в 4-5к км от сервера!..
Все гости форума могут просматривать этот раздел. Только зарегистрированные пользователи могут создавать новые темы в этом разделе. Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.