SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 20.04.2014 20:31:33

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Медленная скорость простого запроса на большой таблице

Привет всем!

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

Имеется таблица:

show create table phrases;
CREATE TABLE `phrases` (
  `phraseid` int(10) unsigned NOT NULL,
  `wordid` int(10) unsigned NOT NULL,
  `langid` tinyint(3) unsigned NOT NULL,
  `wordsnum` tinyint(3) unsigned NOT NULL,
  KEY `phrases_wordid` (`wordid`),
  KEY `phrases_phraseid` (`phraseid`),
  KEY `phrases_wordid_langid` (`wordid`,`langid`),
  KEY `phrases_wordid_langid_wordsnum` (`wordid`,`langid`,`wordsnum`),
  KEY `phrases_langid` (`langid`),
  CONSTRAINT `phrases_ibfk_1` FOREIGN KEY (`wordid`)
      REFERENCES `words` (`wordid`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `phrases_ibfk_2` FOREIGN KEY (`langid`)
      REFERENCES `langs` (`langid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

mysql> select count(*) from phrases;
+----------+
| count(*) |
+----------+
|  1253909 |
+----------+

При попытке выполнить простейший запрос:

SELECT DISTINCT phraseid
FROM   phrases
FORCE INDEX (phrases_wordid_langid)
WHERE phrases.wordid IN (967213)
  AND phrases.langid = 2;
148 rows in set (0.14 sec)

Время выполнения варьируется от ~0,10 до 2 секунд.
Смотрим план выполнения запроса с помощью explain:

+-----------------------+-----------------------+---------+-------------+------+------------------------------+
| possible_keys         | key                   | key_len | ref         | rows | Extra                        |
+-----------------------+-----------------------+---------+-------------+------+------------------------------+
| phrases_wordid_langid | phrases_wordid_langid | 5       | const,const |  148 | Using where; Using temporary |
+-----------------------+-----------------------+---------+-------------+------+------------------------------+

Правильно ли я понимаю, что Using temporary здесь в виду недостатка памяти для размещения всего индекса таблицы?
Как вообще можно ускорить выполнения данного запроса?
Заранее спасибо!

Отредактированно FiMko (20.04.2014 20:35:59)

Неактивен

 

#2 20.04.2014 21:10:34

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Медленная скорость простого запроса на большой таблице

USING TEMPORARY из-за DISTINCT. Сначала он выбирает по ключу во временную таблицу, а затем применяет алгоритм DISTINCT.

Неактивен

 

#3 20.04.2014 21:23:35

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Медленная скорость простого запроса на большой таблице

rgbeast, спасибо, точно! Но как решить проблему низкой производительности?

mysql> SELECT phraseid
    -> FROM   phrases
    -> WHERE phrases.wordid = 1113000;
+----------+
| phraseid |
+----------+
|   209012 |
|   216052 |
|   219552 |
|   284499 |
|   296333 |
|   298996 |
|   302625 |
|   308975 |
+----------+
8 rows in set (0.12 sec)

explain:

+----------------+---------+-------+------+-------+
| key            | key_len | ref   | rows | Extra |
+----------------+---------+-------+------+-------+
| phrases_wordid | 4       | const |    8 |       |
+----------------+---------+-------+------+-------+

Выкрутил настройки mysql (с перезапуском MySQL, конечно):

# memory
key_buffer_size = 32M
table_cache = 256
max_connections = 650
sort_buffer_size = 32M
query_cache_limit = 2M
query_cache_size = 64M
query_cache_type = 1
thread_cache_size = 4

Никаких улучшений...

Отредактированно FiMko (20.04.2014 21:24:14)

Неактивен

 

#4 20.04.2014 22:31:13

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Медленная скорость простого запроса на большой таблице

А чему равна переменная innodb_buffer_pool_size?

Худший случай, если это 8 обращений в разные области диска. Лучший, если уже вся таблица полностью в буферпуле (в памяти).

Note: на всякий случай учитывайте, что первичный ключ в InnoDB работает несколько быстрее вторичных

Неактивен

 

#5 20.04.2014 22:55:31

FiMko
Активист
Откуда: Санкт-Петербург
Зарегистрирован: 18.09.2009
Сообщений: 198

Re: Медленная скорость простого запроса на большой таблице

innodb_buffer_pool_size = 256M

На таблице phrases вообще нет primary, показался не нужен.
Я в принципе не могу понять почему такая медленная скорость 6 rows in set (0.10 sec).
Индексы есть и выбираются правильные, данных в таблице относительно немного (1 253 909 строк).

---
Сейчас попробовал на сервере (1ГБ RAM, SSD HDD), там очень быстро выполняется. Видимо, на локальном ноутбуке с IDE SATA HDD имеют место быть накладные расходы на disk IO. Как бы проверить (из любопытства)...

Неактивен

 

#6 20.04.2014 23:22:50

rgbeast
Администратор
MySQL Authorized Developer and DBA
Откуда: Москва
Зарегистрирован: 21.01.2007
Сообщений: 3880

Re: Медленная скорость простого запроса на большой таблице

смотрите iostat или iotop под нагрузкой

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson