0

これに対する答えは、別のインデックスを持つことにあると確信しています。非常に遅いクエリがありますが、次の完全な形式の場合にのみ、クエリの一部を削除すると非常に高速になります。どうすれば改善できますか?

遅い:

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

Neo が提案したようにインデックスを更新すると、劇的な改善が得られます。

+----+-------------+----------+------+-------------------+-------------------+---------+-------------+------+------------------------------+
| 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 |
+----+-------------+----------+------+-------------------+-------------------+---------+-------------+------+------------------------------+
4

3 に答える 3

1
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);
于 2011-04-07T09:04:02.937 に答える
0

これはどうですか?

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;

そして、クモ畑にインデックスを付けることはあなたを助けるかもしれません。

于 2011-04-07T08:53:19.153 に答える
0

いくつかのコメント/提案:

  • Slow SELECT ステートメントでMySQL Explain ステートメントを使用してみましたか? これにより、おそらく問題のいくつかの兆候が得られます。
  • 遅いクエリの問題は、WHERE 句にスパイダーと load_count の両方が含まれているが、両方のフィールドをカバーするインデックスがないことだと思われます。両方のインデックスを追加すると、おそらくこの例が修正されます。
  • 最初の 2 つのクエリでは、WHERE に「AND load_count < 50」が含まれていますが、「load_count = [正確な値]」も含まれているため、これは必要ありません。MySQL は、クエリの最適化で「AND load_count < 50」を無視します。
于 2011-04-07T08:58:49.927 に答える