- 我的查询大约需要 2800 秒才能获得输出。
- 我们也有索引,但没有运气。
- 我的目标是需要在 2 到 3 秒内获得输出。
如果可能,请重新编写查询。
query: select ttl.id, ttl.url, ttl.canonical_url_id from t_target_url ttl where ttl.own_domain_id=476 and ttl.type != 10 order by ttl.week_entrances desc limit 550000; Explain Plan: +----+-------------+-------+------+--------------------------------+---------------------------+---------+-------+----------+-----------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+--------------------------------+---------------------------+---------+-------+----------+-----------------------------+ | 1 | SIMPLE | ttl | ref | own_domain_id_type_status,type | own_domain_id_type_status | 5 | const | 57871959 | Using where; Using filesort | +----+-------------+-------+------+--------------------------------+---------------------------+---------+-------+----------+-----------------------------+ 1 row in set (0.80 sec) mysql> show create table t_target_url\G *************************** 1. row *************************** Table: t_target_url Create Table: CREATE TABLE `t_target_url` ( `id` int(11) NOT NULL AUTO_INCREMENT, `own_domain_id` int(11) DEFAULT NULL, `url` varchar(2000) NOT NULL, `create_date` datetime DEFAULT NULL, `friendly_name` varchar(255) DEFAULT NULL, `section_name_id` int(11) DEFAULT NULL, `type` int(11) DEFAULT NULL, `status` int(11) DEFAULT NULL, `week_entrances` int(11) DEFAULT NULL COMMENT 'last 7 days entrances', `week_bounces` int(11) DEFAULT NULL COMMENT 'last 7 days bounce', `canonical_url_id` int(11) DEFAULT NULL COMMENT 'the primary URL ID, NOT allow canonical of canonical', KEY `id` (`id`), KEY `urlindex` (`url`(255)), KEY `own_domain_id_type_status` (`own_domain_id`,`type`,`status`), KEY `canonical_url_id` (`canonical_url_id`), KEY `type` (`type`,`status`) ) ENGINE=InnoDB AUTO_INCREMENT=227984392 DEFAULT CHARSET=utf8 /*!50100 PARTITION BY RANGE (`type`) (PARTITION p0 VALUES LESS THAN (0) ENGINE = InnoDB, PARTITION p1 VALUES LESS THAN (1) ENGINE = InnoDB, PARTITION p2 VALUES LESS THAN (2) ENGINE = InnoDB, PARTITION pEOW VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */ 1 row in set (0.00 sec)
1 回答
您的查询本身看起来不错,但是 order by 子句和可能的 50 万条记录可能是您的杀手锏。我会添加一个索引来帮助优化该部分
( own_domain_id, week_entrances, type )
所以这样,你首先点击你的关键键“own_domain_id”,然后让一切都井井有条。该类型是 != 10,因此是任何其他类型,如果它位于第二个索引位置,似乎会导致更多问题。
评论反馈。
为简单起见,每个 where 子句的关键键是“ttl.own_domain_id=476”。您只关心域 ID 476 的数据。现在,假设您有 15 个“类型”,它们跨越所有不同的周入口,例如
own_domain_id type week_entrances
476 1 1000
476 1 1700
476 1 850
476 2 15000
476 2 4250
476 2 12000
476 7 2500
476 7 5300
476 10 1250
476 10 4100
476 12 8000
476 12 3150
476 15 5750
476 15 27000
这显然不是为了扩展您的 50 万容量,而是显示示例数据。通过具有类型!= 10,它仍然必须清除 id=476 的所有记录,但仅排除类型 = 10 的记录。然后它必须按周入口将所有数据按顺序排列,这将花费更多时间。通过将星期入口作为第二个位置的键的一部分,然后是类型,数据将能够在返回的结果集中以正确的顺序进行优化。但是,当它达到“!= 10”的类型时,它仍然会在遇到它们时快速跳过它们。这是每个上述样本的修订索引数据。
own_domain_id week_entrances type
476 850 1
476 1000 1
476 1250 10
476 1700 1
476 2500 7
476 3150 12
476 4100 10
476 4250 2
476 5300 7
476 5750 15
476 8000 12
476 12000 2
476 15000 2
476 27000 15
因此,正如您所看到的,数据已经根据索引进行了预排序,并且应用 DESCENDING 顺序对引擎来说没有问题,只需以相反的顺序提取记录并在找到 10 时跳过它们。
这有帮助吗?
每个 Salman 的附加评论反馈。
以另一种方式考虑一家拥有 10 个不同分店的商店,每个分店都有自己的销售额。交易收据存储在盒子中(字面意思)。想一想如果您要查找给定日期的所有交易,您将如何查看这些框。
Box 1 = Store #1 only, and transactions sorted by date
Box 2 = Store #2 only, and transactions sorted by date
Box ...
Box 10 = Store #10 only, sorted by date.
您必须通过 10 个盒子,在给定日期全部取出...或者在原始问题中,除了一个日期之外的每笔交易,并且您希望它们按交易金额按美元顺序排列,无论日期如何...什么可能是一团糟。
如果您对盒子进行了预先分组,无论商店如何
Box 1 = Sales from $1 - $1000 (all properly sorted by amount)
Box 2 = Sales from $1001 - $2000 (properly sorted)
Box ...
Box 10... same...
您仍然必须检查所有框并将它们按顺序排列,但至少,当您查看交易时,您可以丢弃一个以忽略日期排除。
索引有助于预先组织引擎如何根据您的标准最好地通过它们。