Оптимизация Mysql Query (группировка и упорядочение по -> Использование индекса; Использование временного; Использование файловой сортировки) - PullRequest
1 голос
/ 01 ноября 2010

Вот мой SHOW CREATE TABLE tbl:

CREATE TABLE IF NOT EXISTS `msc_pagestats` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `domain` varchar(250) NOT NULL,
  `file` varchar(200) NOT NULL,
  `simbol` varchar(100) NOT NULL,
  `request_time` timestamp NULL default CURRENT_TIMESTAMP,
  `querystring` mediumtext NOT NULL,
  `host` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `myindex` (`simbol`,`request_time`,`file`,`domain`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin2 AUTO_INCREMENT=248008 ;

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

Мой запрос:

SELECT  `simbol`, count(*) AS requests
 FROM msc_pagestats 
 WHERE 1=1 AND request_time > '20100504000000' 
        AND simbol NOT LIKE ''
 GROUP BY `simbol`
        ORDER BY requests DESC
 LIMIT 0, 15;

Этот запрос ОБЪЯСНЕН:

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra

1  SIMPLE  msc_pagestats  index  NULL  myindex  561  NULL  24961  Using where; Using index; Using temporary; Using filesort

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

Вот что я пытался сделать, чтобы избавиться от использования временного и сортировки файлов:

  1. Добавление идентификатора в качестве первичного ключа и использование COUNT(id) AS requests вместо COUNT(*) AS requests;
  2. Удаление where 1=1 и simbol not like='', однако, это не доказывает большой разницы;
  3. Добавление нескольких индексов вместо регулярного индекса, ранее в каждом столбце были индексыex (KEY (request_time), KEY (файл), KEY (домен), KEY (символ)).

Я не так хорош в оптимизации, поэтому у меня закончились варианты.

Вот дамп моего файла mysq_slow_query:

Query_time: 3 Lock_time: 0 Rows_sent: 15 Rows_examined: 220297

use kmarket;
SELECT  `simbol`, count(*) AS requests
 FROM msc_pagestats 
 WHERE 1=1 AND request_time > '20100504000000' 
        AND simbol NOT LIKE ''
        GROUP BY `simbol`
 ORDER BY requests DESC
 LIMIT 0, 15;

Любая помощь будет оценена, спасибо:)

1 Ответ

1 голос
/ 01 ноября 2010

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

Индекс на (request_time, simbol) может позволить оптимизатору быстрее исключить много строк, а также уменьшить длину ключа.

...