繁体   English   中英

MySQL I / O绑定InnoDB查询优化问题,而没有将innodb_buffer_pool_size设置为5GB

[英]MySQL I/O bound InnoDB query optimization problem without setting innodb_buffer_pool_size to 5GB

我陷入了MySQL设计可扩展性问题。 任何帮助将不胜感激。

要求:

存储用户在其社交图中关于每个用户的SOCIAL_GRAPH和USER_INFO。 每秒发生许多并发读取和写入。 脏读是可以接受的。

当前设计:

我们有2个(相关)表。 两种InnoDB都用于行锁定,而不是表锁定。

  1. USER_SOCIAL_GRAPH表将已登录的(user_id)映射到另一个(related_user_id)。 主键组合user_id和related_user_id。

  2. USER_INFO表,其中包含有关每个相关用户的信息。 主键为(related_user_id)。

注1:未定义关系。

注2:现在每个表的大小约为1GB,分别具有800万条记录和200万条记录。

简化的表SQL创建:

CREATE TABLE `user_social_graph` (
  `user_id` int(10) unsigned NOT NULL,
  `related_user_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`related_user_id`),
  KEY `user_idx` (`user_id`)
) ENGINE=InnoDB;

CREATE TABLE `user_info` (
  `related_user_id` int(10) unsigned NOT NULL,
  `screen_name` varchar(20) CHARACTER SET latin1 DEFAULT NULL,
  [... and many other non-indexed fields irrelevant]
  `last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`related_user_id`),
  KEY `last_updated_idx` (`last_updated`)
) ENGINE=InnoDB;

MY.CFG值设置为:

innodb_buffer_pool_size = 256M
key_buffer_size         = 320M

注3:可用内存为1GB,这两个表为2GB,其他innoDB表为3GB。

问题:

以下示例SQL语句需要访问找到的所有记录,需要15秒执行(!!),并且num_results = 220,000:

SELECT SQL_NO_CACHE COUNT(u.related_user_id) 
FROM user_info u LEFT JOIN user_socialgraph u2 ON u.related_user_id = u2.related_user_id 
WHERE u2.user_id = '1' 
AND u.related_user_id = u2.related_user_id 
AND (NOT (u.related_user_id IS NULL));

对于计数为30,000的user_id,大约需要3秒(!)。

对220,000个计数用户的EXPLAIN EXTENDED。 它使用索引:

+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
| id | select_type | table | type   | possible_keys          | key      | key_len | ref                | rows   | filtered | Extra                    |
+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
|  1 | SIMPLE      | u2    | ref    | user_user_idx,user_idx | user_idx | 4       | const              | 157320 |   100.00 | Using where              |
|  1 | SIMPLE      | u     | eq_ref | PRIMARY                | PRIMARY  | 4       | u2.related_user_id |      1 |   100.00 | Using where; Using index |
+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+

如何在不将innodb_buffer_pool_size设置为5GB的情况下加快速度?

谢谢!

user_social_graph表未正确索引!!!

您有:

创建表user_social_graph
user_id int(10)unsigned NOT NULL,
related_user_id int(11)NOT NULL,
主键( user_idrelated_user_id ),
密钥user_idxuser_id ))
ENGINE = InnoDB的;

由于第一列是user_id,因此第二个索引是冗余的。 您正在尝试将related_user_id列加入到user_info表中。 该列需要索引。

如下更改user_social_graphs:

创建表user_social_graph
user_id int(10)unsigned NOT NULL,
related_user_id int(11)NOT NULL,
主键( user_idrelated_user_id ),
唯一键related_user_idxrelated_user_iduser_id ))
ENGINE = InnoDB的;

这应该更改“解释计划”。 请记住,索引顺序很重要,具体取决于查询列的方式。

试试看 !!!

  1. 什么是MySQL版本? 它的手册包含重要的信息,这些信息通常可以加快语句和代码的速度。

  2. 将您的范例更改为能够管理到TB级表的数据仓库。 使用免费工具或应用程序将旧版MySQL数据库迁移到新范例中。 这是一个示例: http : //www.infobright.org/Downloads/What-is-ICE/许多其他(免费和商业)。

  3. PostgreSQL不是商业性的,有很多工具可以将MySQL迁移到它!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM