- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在处理一个包含 250 多万行的巨大表格。模式很简单。
CREATE TABLE MyTable (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
oid INT NOT NULL,
long1 BIGINT NOT NULL,
str1 VARCHAR(30) DEFAULT NULL,
str2 VARCHAR(30) DEFAULT NULL,
str2 VARCHAR(200) DEFAULT NULL,
str4 VARCHAR(50) DEFAULT NULL,
int1 INT(6) DEFAULT NULL,
str5 VARCHAR(300) DEFAULT NULL,
date1 DATE DEFAULT NULL,
date2 DATE DEFAULT NULL,
lastUpdated TIMESTAMP NOT NULL,
hashcode INT NOT NULL,
active TINYINT(1) DEFAULT 1,
KEY oid(oid),
KEY lastUpdated(lastUpdated),
UNIQUE KEY (hashcode, active),
KEY (active)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 MAX_ROWS=1000000000;
insert 的性能明显下降。高达1.5亿行的表,以前插入10000行需要5-6秒。现在涨了2-4倍。 Innodb 的 ibdata 文件已经增长到 107 GB。 Innodb配置参数如下。
innodb_buffer_pool_size = 36G # Machine has 48G memory
innodb_additional_mem_pool_size = 20M
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_file_size = 50M
innodb_log_buffer_size = 20M
innodb_log_files_in_group=2
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
innodb_thread_concurrency = 8
innodb_flush_method = O_DIRECT
expire_logs_days = 4
如 top
所示,IO 等待时间增加了。我曾尝试将刷新方法更改为 O_DSYNC,但没有帮助。该磁盘是从硬件 RAID 10 设置中分割出来的。在早期的单磁盘设置中,IO 不是问题。
分区表是唯一的选择吗?将单个 100G 文件拆分成“更小”的文件有帮助吗?是否有任何变量需要针对 RAID 进行调整?
更新:这是一个测试系统。我可以自由地进行任何必要的更改。
最佳答案
您没有说明这是测试系统还是生产系统;我假设它正在生产。
很可能您已将表的大小设置为其索引(或全部索引)不再适合内存。
这意味着 InnoDB 必须在插入期间读入页面(取决于新行索引值的分布)。阅读页面(随机阅读)真的很慢,需要尽可能避免。
分区似乎是最明显的解决方案,但 MySQL 的分区可能不适合您的用例。
您当然应该考虑所有可能的选择 - 将表放到您实验室的测试服务器上以查看其行为方式。
在我看来,您的主键似乎不是必需的(您有另一个唯一索引),因此消除它是一种选择。
还要考虑 innodb 插件和压缩,这将使你的 innodb_buffer_pool 更进一步。
您确实需要分析您的用例,以确定您是否真的需要保留所有这些数据,以及分区是否是一个明智的解决方案。
对此应用程序进行任何更改都可能会给您的用户带来新的性能问题,因此您在这里要格外小心。如果您找到提高插入性能的方法,它可能会降低搜索性能或其他操作的性能。在发布此类更改之前,您需要对生产级硬件进行全面的性能测试。
关于MySQL Insert 性能在大表上下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3676209/
我正在开发一些用于计费的数据库项目(PHP/MySQL)。 每当创建新账单时,我想生成一个由年、周和增量编号组成的账单编号。我想用触发器来做到这一点。触发器将使用现有的账单编号来查找增量编号,或者从新
我有一个 MySQL 插入,我正在使用 RAND 生成随机 INT 值问题是它不会插入到数据库中,因为该列接受 TINYINT ,如何将输出转换为 TINYINT。代码示例如下: INSERT INT
如果我想从单个插入中保存主键 (mytable_id),我已完成以下操作: CREATE OR REPLACE FUNCTION myfunct(ownerid text) RETURNS void
为了简单起见,假设我有两个表 用户表(id,email) 用户日志表(id, date) 无论 id 被插入到 user 表中,相同的 id 也应该被插入到 user_log 表中,否则事务应该失败。
为了简单起见,假设我有两个表 用户表(id,email) 用户日志表(id, date) 无论 id 被插入到 user 表中,相同的 id 也应该被插入到 user_log 表中,否则事务应该失败。
我知道在触发器中 - 至少对于 SQL Server - 人们永远不应该假设插入的表只有一行,这意味着触发器中这样的 SQL 通常是不好的: select @UserID = ID from inse
我正在使用 bigquery 对象中的方法 tabledata().insertAll 更新行列表。执行后,返回显示没有错误。但是,我的表仍然继续,没有写入任何数据。 可能是权限问题。如果是这样,为什
这是一个扩展 F# Recursive Tree Validation 的问题,我昨天已经很好地回答了。 这个问题涉及在现有树中插入一个 child 。这是我想使用的更新类型: type Name
我有 2 个表:用户和照片(在 mysql 数据库中)。 在这里你可以看到两个表之间的关系 User Photos -------------
我试图同时在不同的表上插入两行。 子查询INSERT INTO的AUTO_INCRMENT或id的值(如果已经存在)应该写入主查询中。 目前我有这个(仅用 3 个值简化),但它不起作用。我想知道是否有
我有一个 900 万行的表,由于其庞大的规模,我正在努力处理所有这些数据。 我想做的是在不覆盖数据的情况下将 IMPORT 一个 CSV 添加到表中。 在我做这样的事情之前; INSERT if no
我正在写新闻并将其插入到我的数据库中,我在 3 年前构建了代码并且运行良好,但我不能再插入了,我不明白为什么: $insert=mysqli_query($co,"INSERT INTO articl
我正在尝试编写一个简单的 INSERT 语句来将新用户添加到数据库中,但它不起作用,这意味着,我尝试插入到表中的数据都没有被插入。几个小时以来,我一直在尝试解决此问题,但没有成功。我尝试编写插入语句的
所以我有这个表格: http://i.imgur.com/vZYssQy.png 现在 ID、First Name、Last Name、DOB、Address、Phone Number 和 Post
在控制台中运行查询(SELECT 语句)时,从数据库检索到的数据以表格格式显示在数据库控制台工具窗口的结果 Pane 中。 我已经搜索过 datagrip Help我只是想知道是否有任何方法可以用于为
每当使用触发器插入行时,我都试图将另一行插入表中,但收到以下错误消息: The target table 'EDDSDBO.Redaction' of the DML statement cannot
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎与 help center 中定义的范围内的编程无关。 . 关闭 6 年前。 Improve
我有以下代码片段: $get_data = mysqli_query ($connect, "SELECT * FROM users WHERE username = '$username'");
情况:需要向 SQLite 数据库中插入大量数据。 问题:我们可以使用两个语句来插入数据 - data = [("111", "222", "333"), ("AAA", "BBB", "CCC"),
我的数据库中有一个表 Teacher: TABLE Teacher ( ID CHAR (7) NOT NULL , name
我是一名优秀的程序员,十分优秀!