插入300万行的表格很慢

时间:2014-11-12 23:34:03

标签: mysql sql-optimization

我有以下MySQL查询:

INSERT INTO shopious_instagram_item_viewer (created, viewer_id, item_id) VALUES ('2014-11-11 21:26:53', 210054, 714755)\G

以下是表的结构:

enter image description here

我想知道为什么这样一个简单的插件会根据percona工具包的分析平均花费37秒来完成。

# Query 2: 0.00 QPS, 0.09x concurrency, ID 0x32289FAFEDA31EE5 at byte 271077009
# This item is included in the report because it matches --limit.
# Scores: V/M = 4.60
# Time range: 2014-11-07 07:12:26 to 2014-11-13 06:18:39
# Attribute    pct   total     min     max     avg     95%  stddev  median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count          0    2459
# Exec time     16  48495s      1s     52s     20s     37s     10s     19s
# Lock time      0   256ms    21us   122ms   104us    54us     3ms    38us
# Rows sent      0       0       0       0       0       0       0       0
# Rows examine   0       0       0       0       0       0       0       0
# Query size     0 287.03k     115     120  119.53  118.34    0.72  118.34
# String:
# Databases    ShopiousDirectory
# Hosts        localhost
# Users        root
# Query_time distribution
#   1us
#  10us
# 100us
#   1ms
#  10ms
# 100ms
#    1s  #############
#  10s+  ################################################################
# Tables
#    SHOW TABLE STATUS FROM `ShopiousDirectory` LIKE 'shopious_instagram_item_viewer'\G
#    SHOW CREATE TABLE `ShopiousDirectory`.`shopious_instagram_item_viewer`\G
INSERT INTO shopious_instagram_item_viewer (created, viewer_id, item_id) VALUES ('2014-11-11 21:26:53', 210054, 714755)\G

我打算添加索引,但不要认为这对插入有很大帮助。

2 个答案:

答案 0 :(得分:0)

您可以在插入之前禁用FK检查,并在以下之后重新启用它们:

SET foreign_key_checks=0;
...SQL QUERY...
SET foreign_key_checks=1;

答案 1 :(得分:0)

这张桌子你INSERT并没有什么奇怪的。只要它执行插入就不应该花费。

但是,您的问题中缺少很多信息。

  1. 您使用的是哪种访问方式?
  2. 您是否插入了大量行并获得了20秒的平均插入时间,或者您只是偶尔插入一行?你每天做了大约400次插入。他们是每天一次,一大堆,还是一次一两次完成?
  3. 您的应用程序在此表上执行的其他部分是什么类型的读取流量?您是否正在运行大量必须读取大量行(聚合等)的查询,或者您偶尔会在这里或那里阅读一两行?
  4. 来自Percona的统计数据 - 在第95百分位时间和最坏情况时间之间存在如此大的差异 - 让我觉得你在插入物和桌面上的其他交通之间存在争用,并且桌子上的其他交通是持续而沉重的。

    在应用程序安静时尝试执行插入操作。如果这可以提高您的INSERT性能,那么您就会知道糟糕的性能是读写之间的争用。

    您使用的是InnoDB吗?如果是这样,请尝试将一堆INSERT语句包装到单个事务中。就是这样做......

    BEGIN;
    INSERT INTO table (col, col, col) VALUES (val, val, val);
    INSERT INTO table (col, col, col) VALUES (val, val, val);
    ... between ten and 100 of these ....
    INSERT INTO table (col, col, col) VALUES (val, val, val);
    INSERT INTO table (col, col, col) VALUES (val, val, val);
    COMMIT;
    

    这会对表格进行批量更改并使事情变得更快。如果您偶尔只有偶然的INSERT操作,它将无济于事。

    您使用的是MyISAM吗?如果是这样,请忘记交易。但是,试试

    INSERT DELAYED INTO table (col, col, col) VALUES (val, val, val);
    

    这将在数据库服务器内排队插入;它是一种用于插入的发送 - 遗忘方案。插入操作排队等候,直到竞争SELECT并完成其他操作。

    而且,归根结底,每天400行的平均插入时间为20秒,对于您的应用来说可能不是灾难性的,即使它确实很慢。