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

一些意见/建议:

  • 您是否尝试过在慢速 SELECT 语句上使用MySQL 解释语句?这可能会给你一些问题的迹象。
  • 我怀疑慢查询的问题是它在 WHERE 子句中同时具有蜘蛛和 load_count,但没有涵盖这两个字段的索引。添加两者的索引可能会解决此示例。
  • 前两个查询在 WHERE 中有“AND load_count < 50”,这不是必需的,因为您还有一个“load_count = [exact value]”。MySQL 将在其查询优化中忽略“AND load_count < 50”。
于 2011-04-07T08:58:49.927 回答