如果可能请重新编写查询。
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)
答案 0 :(得分:4)
您的查询本身看起来很好,但是,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...
你仍然必须通过所有方框并按顺序排列它们,但至少,当你查看交易时,你可以抛出一个日期排除以忽略。
索引有助于预先组织引擎如何根据您的标准最好地完成这些操作。