问题
I have 2 MySQL databases on 2 separate cloud servers. One is setup by my colleague and I duplicated that one with same structures.
Days ago I found a query on my database is slow but fast in his database. Then he told me he added 2 indexes for a table and he added the same 2 indexes for my database but it just didn't work and he didn't know why.
The explain result is different after adding the same indexes. And my query is still slow.
(0.36s vs > 3mins)
Could you tell me what's wrong and help me understand the explain result and the differences ?
Query:
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
table strcuture:
# 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)
His 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 `inx_rid` (`rid`),
KEY `inx_uid` (`uid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
Explain result of the above query:
On my DB:
+----+-------------+------------+-------+---------------+---------+---------+------+--------+--------------------------------+
| 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 |
+----+-------------+------------+-------+---------------+---------+---------+------+--------+--------------------------------+
On his DB:
+----+-------------+------------+-------+-------------------------+-------------+---------+--------------------------------------+--------+--------------------------+
| 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 |
+----+-------------+------------+-------+-------------------------+-------------+---------+--------------------------------------+--------+--------------------------+
Each table row count: https://dpaste.com/AZ5KU4JCV
The above query takes 0.36s in his db but more than 3 mins in mine..
Why the explain result and order are different and what does it say? I just learnt some basic about index and am not familiar with explain result at all.
Also, I was planning to try a composite index with (I read the indexes wrong and this is totally useless.)(rid, uid) if I succeeded speeding up the query by adding the same indexes but I failed.
Update:
Ok. The MySQL verion is different, mine is Server version: 5.1.73 Source distribution and his is Server version: 5.6.48 MySQL Community Server (GPL).. I would dump the data from my DB and try on his MySQL for now...
回答1:
t_pay_history_real needs INDEX(uid, srv_id)
t_ids might be helped by INDEX(reg_srv_id, uid)
Note that you are running different versions: <auto_key0> indicates a newer version.
Switching from ENGINE=MyISAM to ENGINE=InnoDB should be beneficial in many ways.
If you add INDEX(rid, uid), remove INDEX(rid) as being useless. However I don't see any need for it for this query.
回答2:
The giveaway is the <auto_key0> key used in the derived table on your friend's server. This is not a key created by your friend, this is a key generated by mysql automatically as part of subquery materialization optimization technique.
This optimization technique was added in mysql v5.6.5, therefore your ancient mysql version can't take advantage of it. It is time to upgrade! Both of you...
来源:https://stackoverflow.com/questions/65905995/same-database-structure-and-index-but-different-query-speed-and-explain-results