相同的数据库结构和索引,但不同的查询速度和解释结果
我在 2 个独立的云服务器上有 2 个 MySQL 数据库。一个是我的同事设置的,我用相同的结构复制了那个。
几天前,我发现对我的数据库的查询很慢,但在他的数据库中却很快。然后他告诉我他为一个表添加了 2 个索引,他为我的数据库添加了相同的 2 个索引,但它不起作用,他不知道为什么。添加相同索引后
的explain结果是不同的。我的查询仍然很慢。
(0.36s对比> 3mins)
你能告诉我出了什么问题并帮助我理解explain结果和差异吗?
询问:
select sum(A.money) from
stat_sword.t_pay_history_real as A,
inner join
(select uid, reg_srv_id as srv_id
from sword_common.t_ids
where reg_srv_id < 100000
group by uid having count(uid) > 1) as B
on A.uid = B.uid and A.srv_id = B.srv_id
表结构:
# Same t_pay_history_real for both databases
mysql> show create table stat_sword.t_pay_history_real G;
*************************** 1. row ***************************
Table: t_pay_history_real
Create Table: CREATE TABLE `t_pay_history_real` (
`time` int(11) NOT NULL,
`srv_id` int(11) NOT NULL,
`uid` int(11) NOT NULL,
`money` int(11) NOT NULL,
`item_id` int(11) DEFAULT '0',
`count` int(11) DEFAULT '0',
`ingot` int(11) DEFAULT '0',
`rid` int(11) DEFAULT '0',
`span_id` int(11) DEFAULT '0',
`orderid` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`time`,`srv_id`,`uid`,`orderid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
# My sword_common.t_ids
mysql> show create table Sword_common.t_ids G;
*************************** 1. row ***************************
Table: t_ids
Create Table: CREATE TABLE `t_ids` (
`uid` int(10) unsigned NOT NULL DEFAULT '0',
`reg_srv_id` int(11) NOT NULL DEFAULT '0',
`rid` int(10) unsigned NOT NULL DEFAULT '0',
`span_id` int(11) DEFAULT '0',
`cur_srv_id` int(11) DEFAULT '0',
`reg_time` int(10) unsigned DEFAULT '0',
`com_time` int(10) unsigned DEFAULT '0',
PRIMARY KEY (`uid`,`reg_srv_id`),
KEY `idx_rid` (`rid`),
KEY `idx_uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
他的剑_common.t_ids
mysql> show create table sword_common.t_ids G;
*************************** 1. row ***************************
Table: t_ids
Create Table: CREATE TABLE `t_ids` (
`uid` int(10) unsigned NOT NULL DEFAULT '0',
`reg_srv_id` int(11) NOT NULL DEFAULT '0',
`rid` int(10) unsigned NOT NULL DEFAULT '0',
`span_id` int(11) DEFAULT '0',
`cur_srv_id` int(11) DEFAULT '0',
`reg_time` int(10) unsigned DEFAULT '0',
`com_time` int(10) unsigned DEFAULT '0',
PRIMARY KEY (`uid`,`reg_srv_id`),
KEY `inx_rid` (`rid`),
KEY `inx_uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
Explain 上面查询的结果:
在我的数据库上:
+----+-------------+------------+-------+---------------+---------+---------+------+--------+--------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+---------------+---------+---------+------+--------+--------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 26778 | |
| 1 | PRIMARY | A | ALL | NULL | NULL | NULL | NULL | 162010 | Using where; Using join buffer |
| 2 | DERIVED | t_ids | index | NULL | idx_uid | 4 | NULL | 335827 | Using where; Using index |
+----+-------------+------------+-------+---------------+---------+---------+------+--------+--------------------------------+
在他的数据库上:
+----+-------------+------------+-------+-------------------------+-------------+---------+--------------------------------------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+-------+-------------------------+-------------+---------+--------------------------------------+--------+--------------------------+
| 1 | PRIMARY | A | ALL | NULL | NULL | NULL | NULL | 315144 | NULL |
| 1 | PRIMARY | <derived2> | ref | <auto_key0> | <auto_key0> | 8 | stat_sword.A.uid,stat_sword.A.srv_id | 10 | Using where; Using index |
| 2 | DERIVED | t_ids | index | PRIMARY,inx_rid,inx_uid | inx_uid | 4 | NULL | 740388 | Using where; Using index |
+----+-------------+------------+-------+-------------------------+-------------+---------+--------------------------------------+--------+--------------------------+
每个表的行数:https : //dpaste.com/AZ5KU4JCV
上面的查询接受0.36s了他的数据库,但比3 mins我的多。
为什么explain结果和顺序不同,它说什么?我刚刚学习了一些关于索引的基础知识,对explain结果完全不熟悉。
另外,我计划尝试一个复合索引, (我读错了索引,这完全没用。)(rid, uid)如果我通过添加相同的索引成功加快了查询,但我失败了。
更新:
好的。MySQL 版本是不同的,我的Server version: 5.1.73 Source distribution和他的不同Server version: 5.6.48 MySQL Community Server (GPL)。
回答
赠品是<auto_key0>您朋友服务器上派生表中使用的密钥。这不是您朋友创建的密钥,这是 mysql 作为子查询物化优化技术的一部分自动生成的密钥。
这个优化技巧是在mysql v5.6.5中加入的,所以你的mysql 旧版本无法利用它。是时候升级了!你们俩...