Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
164 views
in Technique[技术] by (71.8m points)

mysql - same database structure and index, but different query speed and explain results

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 (rid, uid) if I succeeded speeding up the query by adding the same indexes but I failed. (I read the indexes wrong and this is totally useless.)


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...

question from:https://stackoverflow.com/questions/65905995/same-database-structure-and-index-but-different-query-speed-and-explain-results

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...