Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL I/O绑定InnoDB查询优化问题,无需将InnoDB_buffer_pool_size设置为5GB_Mysql_Database_Database Design - Fatal编程技术网

MySQL I/O绑定InnoDB查询优化问题,无需将InnoDB_buffer_pool_size设置为5GB

MySQL I/O绑定InnoDB查询优化问题,无需将InnoDB_buffer_pool_size设置为5GB,mysql,database,database-design,Mysql,Database,Database Design,我陷入了MySQL设计的可伸缩性问题。任何帮助都将不胜感激 要求: 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

我陷入了MySQL设计的可伸缩性问题。任何帮助都将不胜感激

要求:

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;
innodb_buffer_pool_size = 256M
key_buffer_size         = 320M
在用户的社交图中存储用户的社交图和每个用户的用户信息。每秒发生许多并发读写操作。肮脏的阅读是可以接受的

当前设计:

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;
innodb_buffer_pool_size = 256M
key_buffer_size         = 320M
我们有两个(相关)表格。两个InnoDB都用于行锁定,而不是表锁定

  • 将已登录(用户id)映射到另一个(相关用户id)的用户社交图表。主键组合用户标识和相关用户标识

  • 用户信息表,包含每个相关用户的信息。主键是(相关用户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;
    
    innodb_buffer_pool_size = 256M
    key_buffer_size         = 320M
    
    MY.CFG值集:

    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;
    
    innodb_buffer_pool_size = 256M
    key_buffer_size         = 320M
    
    注3:可用内存为1GB,这两个表为2GB,其他innoDB表为3GB

    问题:

    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;
    
    innodb_buffer_pool_size = 256M
    key_buffer_size         = 320M
    
    以下示例SQL语句需要访问找到的所有记录,执行该语句需要15秒(!!),num_results=220000:

    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));
    
    对于计数为30000的用户id,大约需要3秒(!)

    解释针对220000计数用户的扩展。它使用指数:

    +----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
    | 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的情况下加快这些速度


    谢谢大家!

    用户\u社交\u图表未正确索引

    你有:

    创建表格
    user\u social\u图表

    user\u id
    int(10)无符号非空,
    相关用户id
    int(11)不为空,
    主键(
    用户id
    相关用户id
    ),
    按键
    user\u idx
    user\u id

    引擎=InnoDB

    第二个索引是多余的,因为第一列是user\u id。您正在尝试将相关的\u user\u id列加入到user\u info表中。该列需要编制索引

    按如下方式更改用户\社交\图:

    创建表格
    user\u social\u图表

    user\u id
    int(10)无符号非空,
    相关用户id
    int(11)不为空,
    主键(
    用户id
    相关用户id
    ),
    唯一键
    相关用户id
    相关用户id
    用户id

    引擎=InnoDB

    这应该会改变计划。请记住,索引顺序取决于查询列的方式

    试试看

  • MySQL版本是什么?其手册包含加速语句和代码的重要信息

  • 将您的范例更改为能够管理TB级表的数据仓库。使用免费工具或应用程序将遗留的MySQL数据库迁移到新的范例。这是一个例子:许多其他(免费和商业)

  • PostgreSQL不是商业化的,有很多工具可以将MySQL迁移到它


  • 你是对的。该指数不是最佳选择。我做了你建议的改变,但没有用。EXPLAIN计划看起来更好,但它仍然是I/O绑定的,速度很慢(和以前一样)。我不得不使用FORCE KEY FOR JOIN(related_user_idx)让MySQL使用新索引,现在显示在解释中。有什么想法吗?为什么MySQL不使用COUNT()的索引?我至少会将innodb_buffer_pool_大小增加一倍,达到512M。另外,我会将innodb_log_file_大小设置为128M。在/etc/my.cnf中设置这些值后,请确保执行以下操作:1)关闭mysql,2)rm/var/lib/mysql/ib_logfile*,3)针对InnoDB从不使用索引重新启动mysql.COUNT()。当您在InnoDB表中执行“从tblname显示索引”时,每次都会得到不同的基数。这是因为为了MySQL查询优化器的缘故,InnoDB存储引擎确实会将索引潜入索引以猜测基数。因此,通过设计获得表计数时,该索引被认为是完全不可靠的。因此,MySQL每次都会针对InnoDB表启动一次完整的表扫描。感谢您的响应。innodb_buffer_pool_size设置为512M时,速度确实提高了2倍。但我肯定我们错过了什么。正如您从最初的EXPLAIN输出中看到的,它使用的是索引,那么为什么它要从磁盘读取记录来计数呢?页面刚刚更新了您的新注释。关于计数和索引,您是对的。我有一个想法,我不是100%确定如何执行。如果我将这些表转换为MyISAM,是否有办法解决表锁定问题,以便INSERT、DELETE和UPDATE语句几乎可以同时运行?我猜快速和延迟关键字会有所帮助。注意:解释中显示的“user\u user\u idx”与user\u social\u图表的主关键字相同。感谢您的回答,但似乎没有正确的答案。为了使执行时间可接受,我设置了以下my.cfg值:innodb_buffer_pool_size=612M,innodb_flush_method=O_DIRECT(跳过双缓存),innodb_locks_unsafe_for_binlog=1(请参阅)。不是很容易扩展,但是可以接受。您能澄清一下您希望通过此查询实现什么吗?例如,如果您只是想计算ID为1的用户的相关用户ID的数量,那么很简单:从user_-social_图中选择count(*),其中user_-ID=1。此外,您的JOIN和WHERE条件是冗余的。此外,(NOT(u.related_-user_-ID为NULL))中的条件是冗余的,因为相关的用户id被定义为非空。谢谢分享。我现在并不是真的想换一个不同的数据库系统,因为我相信MySQL可以被调整以处理我们现在的几个场景。请你详细说明第二点好吗。也许是链接?另外,为什么您认为PostgreSQL可以解决并发问题?