Пересмотрена проблема производительности таблицы MySQL MyISAM

Этот вопрос связан с этим.

У меня есть таблица page со следующей структурой:

CREATE TABLE  mydatabase.page (
  pageid int(10) unsigned NOT NULL auto_increment,
  sourceid int(10) unsigned default NULL,
  number int(10) unsigned default NULL,
  data mediumtext,
  processed int(10) unsigned default NULL,
  PRIMARY KEY  (pageid),
  KEY sourceid (sourceid)
) ENGINE=MyISAM AUTO_INCREMENT=9768 DEFAULT CHARSET=latin1;

Столбец data содержит текст размером от 80 КБ до 200 КБ на запись. Общий размер данных, хранящихся в столбце data, составляет около 1,5 ГБ.

Выполнение этого запроса занимает 0,08 секунды:

select pageid from page

Но выполнение этого запроса занимает около 130,0 секунд:

select sourceid from page

Как видите, у меня есть первичный индекс для page.pageid и индекс для page.sourceid. Так должен ли второй запрос занимать ЭТО много времени?

Изменить №1

EXPLAIN возвращено

id select_type table type  possible_keys key      key_len ref rows Extra
1  SIMPLE      page  index               sourceid 5           9767 Using index

Извините, но профилирование не сработало... MySQL (4.1.22) не распознал запрос SHOW PROFILE.

Возвращен ПОКАЗАТЬ ИНДЕКС

Table Non_unique Key_name  Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
page  0          PRIMARY   1            pageid      A         9767                             BTREE 
page  1          sourceid  1            sourceid    A         3255                        YES  BTREE 

person Salman A    schedule 11.05.2009    source источник
comment
Пожалуйста, сделайте EXPLAIN выберите sourceid со страницы и включите pforiling для этого запроса: SET profiling = 1;, выполнить запрос, SHOW PROFILE; а затем отключить профилирование SET profiling = 2; и мимо результатов.   -  person Stefan Gehrig    schedule 11.05.2009
comment
Упс - в первую очередь должно читаться профилирование, а не пфорилирование, а затем должно быть SET профилирование = 0; отключить профилирование.   -  person Stefan Gehrig    schedule 11.05.2009
comment
Только что отредактировал пост как просили   -  person Salman A    schedule 11.05.2009


Ответы (3)


Вы пытались принудительно использовать индекс? Нравиться:

SELECT sourceid FROM page USE INDEX (sourceid_index)

Как и комментарии sgehrig, проверьте с помощью EXPLAIN, используется ли индекс? И поделитесь результатом?

EXPLAIN select sourceid from page

Это также может помочь поделиться определением индексов:

SHOW INDEX FROM page
person Andomar    schedule 11.05.2009
comment
Я пересмотрел вопрос и добавил запрошенную вами информацию - person Salman A; 11.05.2009
comment
ааа... выберите sql_no_cache sourceid из индекса использования страницы (sourceid) сработало, и запрос занял 0,09 секунды. По какой-то причине mysql не может самостоятельно определить индекс для использования. теперь мне нужен запрос, который вызывает индекс в каскадном соединении (страница> страница> источник) - person Salman A; 11.05.2009
comment
Можете ли вы действительно подтвердить, что только комбинация SQL_NO_CACHE и USE INDEX дает ожидаемый выигрыш в скорости? Может ли быть, что SQL_NO_CACHE является определяющим фактором? - person Stefan Gehrig; 11.05.2009
comment
Я использую SQL_NO_CACHE для проверки фактической производительности запроса. Если я не использую это ключевое слово (что я обычно и делаю), запрос в первый раз выполняется медленно, позже результаты запроса поступают из кеша, что всегда быстрее, но не решает проблему. SQL_NO_CACHE заставляет mysql не использовать/сохранять результаты в кэше, возвращая фактическое время, которое запрос занимает в нормальных обстоятельствах. - person Salman A; 11.05.2009
comment
Я именно поэтому и спросил - хотел исключить вариант, что кеш запросов как-то влияет на время выполнения. Поэтому очевидно, что MySQL нуждается в подсказке индекса, чтобы использовать покрывающий индекс. - person Stefan Gehrig; 11.05.2009

Насколько отличаются ваши поля sourceid? Если у вас есть только несколько разных значений sourceid по сравнению с количеством строк, вы можете попробовать увеличить размер индекса.

person Sander Marechal    schedule 11.05.2009
comment
sourceid содержит около 3500 различных значений. Он относится к исходной таблице, содержащей около 3500 строк. Каждый источник содержит от 0 до 700 страниц. - person Salman A; 11.05.2009

Поскольку версия MySQL 4.1.22 довольно старая (02 ноября 2006 г.), я подозреваю, что она не поддерживает понятие покрытия индексов для вторичных ключей. EXPLAIN показывает, что запрос фактически использует индекс, поэтому я предполагаю, что требуется дополнительное время для чтения всех строк результата (вместо того, чтобы просто возвращать содержимое индекса при использовании покрывающих индексов) для извлечения sourceid столбец.

Есть ли у вас возможность проверить запрос на более новой версии сервера MySQL?

person Stefan Gehrig    schedule 11.05.2009