SELECT по значению столбца MIN и столбцу CHAR очень медленно в MySQL - PullRequest
0 голосов
/ 07 апреля 2011

Я уверен, что ответ на этот вопрос заключается в наличии другого индекса.У меня есть запрос, который неоправданно медленный, но только когда он находится в следующей полной форме, если я удаляю части запроса, он работает невероятно быстро, как я могу сделать его лучше?

Медленно:

SELECT json
  FROM requests
  WHERE spider = 'foo'
    AND load_count = ( SELECT MIN( load_count ) FROM requests )
    AND load_count < 50
  LIMIT 500;

ОБЪЯСНЕНИЕ:

+----+-------------+----------+------+-------------------------+--------------+---------+-------+--------+------------------------------+
| id | select_type | table    | type | possible_keys           | key          | key_len | ref   | rows   | Extra                        |
+----+-------------+----------+------+-------------------------+--------------+---------+-------+--------+------------------------------+
|  1 | PRIMARY     | requests | ref  | load_count,spider_index | spider_index | 90      | const | 200845 | Using where                  |
|  2 | SUBQUERY    | NULL     | NULL | NULL                    | NULL         | NULL    | NULL  |   NULL | Select tables optimized away |
+----+-------------+----------+------+-------------------------+--------------+---------+-------+--------+------------------------------+

Структура базы данных:

CREATE TABLE `requests` (
  `added` int(11) NOT NULL AUTO_INCREMENT,
  `url` char(255) NOT NULL,
  `spider` char(30) NOT NULL,
  `referer` char(255) DEFAULT NULL,
  `json` text NOT NULL,
  `load_count` int(11) NOT NULL DEFAULT '0',
  `processed` tinyint(1) NOT NULL DEFAULT '0',
  `invalid` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`added`),
  UNIQUE KEY `url` (`url`),
  KEY `load_count` (`load_count`),
  KEY `spider_index` (`spider`)
) ENGINE=MyISAM AUTO_INCREMENT=5285840 DEFAULT CHARSET=utf8

После обновления моего индекса, как предложил Нео, я получил радикальные улучшения:

+----+-------------+----------+------+-------------------+-------------------+---------+-------------+------+------------------------------+
| id | select_type | table    | type | possible_keys     | key               | key_len | ref         | rows | Extra                        |
+----+-------------+----------+------+-------------------+-------------------+---------+-------------+------+------------------------------+
|  1 | PRIMARY     | requests | ref  | spider_load_count | spider_load_count | 94      | const,const | 1487 | Using where                  |
|  2 | SUBQUERY    | NULL     | NULL | NULL              | NULL              | NULL    | NULL        | NULL | Select tables optimized away |
+----+-------------+----------+------+-------------------+-------------------+---------+-------------+------+------------------------------+

Ответы [ 3 ]

1 голос
/ 07 апреля 2011
alter table requests drop index load_count;
alter table requests drop index spider_index;

alter table requests add index spider_load_count(load_count, spider);
0 голосов
/ 07 апреля 2011

Несколько комментариев / предложений:

  • Вы пытались использовать MySQL Explain Statement в вашем медленном операторе SELECT? Это, вероятно, даст вам некоторое представление о проблеме.
  • Я подозреваю, что проблема с медленным запросом заключается в том, что в предложении WHERE есть как spider, так и load_count, но нет индекса, охватывающего оба поля. Добавление индекса с обоими in, вероятно, исправит этот пример.
  • Первые два запроса имеют «AND load_count <50» в WHERE, что не нужно, так как у вас также есть «load_count = [точное значение]». MySQL будет игнорировать «AND load_count <50» при оптимизации запросов. </li>
0 голосов
/ 07 апреля 2011

Как насчет этого?

SELECT MIN(load_count) INTO @min_load_count FROM requests;

SELECT json
  FROM requests
  WHERE load_count = @min_load_count
    AND load_count < 50
  LIMIT 500;

И наличие индекса на поле паука может вам помочь.

...