Ускорьте СЧЕТЫ MySQL (MyISAM) с предложениями WHERE - PullRequest
4 голосов
/ 19 января 2012

Мы внедряем систему, которая анализирует книги. Система написана на PHP, и каждая книга просматривает слова и анализирует каждое из них, устанавливая определенные флаги (которые переводятся в поля базы данных) из различных регулярных выражений и других тестов.

В результате получается таблица matches, аналогичная приведенному ниже примеру:

+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| id                     | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| regex                  | varchar(250) | YES  |     | NULL    |                |
| description            | varchar(250) | NO   |     | NULL    |                |
| phonic_description     | varchar(255) | NO   |     | NULL    |                |
| is_high_frequency      | tinyint(1)   | NO   |     | NULL    |                |
| is_readable            | tinyint(1)   | NO   |     | NULL    |                |
| book_id                | bigint(20)   | YES  |     | NULL    |                |
| matched_regex          | varchar(255) | YES  |     | NULL    |                |
| [...]                  |              |      |     |         |                |
+------------------------+--------------+------+-----+---------+----------------+

Большинство пропущенных полей: tinyint, 0 или 1. В настоящее время в таблице соответствий имеется 25 полей.

В таблице соответствий ~ 2 000 000 строк, результаты анализа ~ 500 книг.

В настоящее время существует область «отчетов» сайта, которая запрашивает таблицу matches, например:

SELECT COUNT(*)
FROM matches
WHERE is_readable = 1
AND other_flag = 0
AND another_flag = 1

Однако в настоящее время получение основного индекса занимает более минуты, поскольку каждый запрос занимает около 0,7 секунды. Я кеширую это на уровне запроса, но это все равно занимает слишком много времени для начальной загрузки страницы.

Поскольку я не очень опытен в управлении такими наборами данных, может ли кто-нибудь посоветовать мне лучший способ хранения или запроса этих данных? Есть ли какие-либо оптимизации, которые я могу использовать с MySQL для повышения производительности этих COUNT s, или мне лучше использовать другую базу данных или структуру данных?

В настоящее время мы используем MySQL с таблицами MyISAM и VPS для этого, поэтому о переходе на новую систему баз данных вообще не может быть и речи.

Ответы [ 2 ]

5 голосов
/ 19 января 2012

Вам нужно использовать индексы, создавать их в столбцах, для которых вы чаще всего используете WHERE.

ALTER TABLE `matches` ADD INDEX ( `is_readable` ) 

и т.д ..

Вы также можете создавать индексы на основе нескольких столбцов, если вы делаете один и тот же тип запроса снова и снова, что полезно. phpMyAdmin имеет опцию индекса на странице структуры таблицы внизу.

4 голосов
/ 19 января 2012

Добавить мультииндекс в эту таблицу, так как вы выбираете более одного поля. Ниже указатель должен сильно помочь. Эти типы индексов очень хороши для столбцов boolean / int. Для индексов со значениями varchar читайте подробнее здесь: http://dev.mysql.com/doc/refman/5.0/en/create-index.html

ALTER TABLE `matches` ADD INDEX ( `is_readable`, `other_flag`, `another_flag` ) 

Еще одна вещь - проверить ваши запросы, используя EXPLAIN {YOUR WHOLE SQL STATEMENT}, чтобы проверить, какой индекс используется БД. Так что в этом примере вы должны выполнить запрос:

EXPLAIN ALTER TABLE `matches` ADD INDEX ( `is_readable`, `other_flag`, `another_flag` ) 

Больше информации на EXPLAIN: http://dev.mysql.com/doc/refman/5.0/en/explain.html

...