在MIN列值和CHAR列上的SELECT在MySQL中确实很慢

时间:2011-04-07 08:43:26

标签: mysql sql sql-optimization

我有理由相信这个问题的答案在于拥有不同的索引。我有一个非常慢的查询,但只有当它处于以下完整形式时,如果我删除部分查询它的速度非常快,我怎样才能让它变得更好?

慢速:

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

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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;

拥有蜘蛛场的索引可能对你有帮助。

答案 2 :(得分:0)

一些意见/建议:

  • 您是否尝试在Slow SELECT语句中使用MySQL Explain Statement?这可能会给你一些问题的指示。
  • 我怀疑慢查询的问题是它在WHERE子句中同时包含spider和load_count,但没有覆盖这两个字段的索引。添加两者的索引可能会修复此示例。
  • 前两个查询在WHERE中有“AND load_count&lt; 50”,这是不需要的,因为您还有“load_count = [exact value]”。 MySQL将忽略其查询优化中的“AND load_count&lt; 50”。