相同的数据库结构和索引,但不同的查询速度和解释结果

我在 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 旧版本无法利用它。是时候升级了!你们俩...


以上是相同的数据库结构和索引,但不同的查询速度和解释结果的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>