【问题标题】:MySQL and queries performanceMySQL 和查询性能
【发布时间】:2016-03-09 17:48:25
【问题描述】:

关于查询和 perl 的最佳实践的问题。

在 perl for 循环中进行选择是否有性能或“坏习惯”?将这么多选择快速发送到数据库是否有问题?

代码是准伪代码

@line 有 5000 行

foreach my $elem( @line ){
    SQL = SELECT IGNORE INTO <table> ( column1, .. , column 10 ) VALUES ( 'a', .. , 'j' )
}

删除和/或更新呢?

foreach my $elem( @line ) {
    my $UN = substr($elem, 0, 10 );
    SQL = UPDATE <table> SET <column> = $UN;
}

foreach my $elem( @line ) {
    my $UN = substr($elem, 0, 10 );
    SQL = DELETE from <table> WHERE <column> = $UN
 }

另外,我在同一个领域有一个问题,我要检查 5000 个项目,而我的数据库在任何给定时间都有 1 个元素到 5000 个元素。是否可以在 perl 中遍历我的 5000 个项目并删除数据库中的 ID,或者是否应该在发出删除命令之前先检查 ID 是否存在。

foreach my $elem ( @line ){
    $ID = substr( $elem, 5, 0 );
    SQL = DELETE FROM <table> WHERE id = $ID;
}

或者应该是这样的:

foreach my $elem ( @line ){
    $ID = substr( $elem, 5, 0 );
    SQL = DELETE FROM <table> WHERE id = $ID if ID exists;
}

谢谢, --Eherr

【问题讨论】:

    标签: mysql database perl


    【解决方案1】:

    至于快速连续插入,不是问题。服务器是专门为处理这个问题而设计的。

    由于其他原因,插入 ignore 时应小心谨慎,例如应解决故障的程序逻辑,否则将无法解决您刚刚忽略的故障。

    至于您展示的特定更新,这在循环中(或者可能根本没有)没有多大意义,因为您没有指定 where 子句。意思是,为什么循环,比如说,1000 次,由于没有 where 子句,每次都对 all 行进行更新?也许这只是你的一个错字。

    至于删除,一般来说,在循环中也没有问题。如果您想清空一张桌子,请查看truncate table,速度更快,如果需要,请不要记录。请注意,在外键约束情况下,对于作为 referenced 表的表,不允许截断。在这些情况下,有引用表和引用的概念。

    其他一般 cmets:应注意确保任何已存在或应存在的引用完整性得到尊重。由于外键约束,执行插入ignore、更新或删除可能会失败。此外,检查是否存在您将要删除的行可能是矫枉过正的 idk。无论如何,它正在沿着 btree 前进以找到它。为什么要做两次(行进部分)。行进可能不是一个好词,也许是飞行。但是在 tablescan 上,它会增加痛苦。

    最后,当您处于大量批量插入的情况时,与 LOAD DATA INFILE 性能相比,循环永远无法胜任任何编程语言的任务。通过使用 LOAD DATA,您的一些同行已经看到 8 到 10 个小时的操作减少到 2 分钟(如果您询问,可以参考链接)。好的This Link 是一个。

    下面的Mysql手册页:

    【讨论】:

    • 是的,这是更新中的拼写错误,我试图通过 5000 次快速更新。我会相应地编辑它。
    • insert ignore 已与表中的唯一键一起使用,因此代替 insert .. 在重复 UPDATE 时,我使用了 INSERT IGNORE
    • 注意为未来应用程序的一般 cmets,但是在这种特殊情况下,我的数据库非常小,不包含外键或所述环境中的任何关系。它仅存储特定应用程序的用户名、IP 地址和状态,用户名是唯一键
    • 可能想补充一点,如果使用prepare,应该在循环之前调用它。虽然转念一想,OP 没有提到 DBI,所以也许他们甚至没有意识到这一点。
    • 嘿@ThisSuitIsBlack不是“我喜欢!!”
    【解决方案2】:

    在我看来,进行多个查询有点慢。最好构造一个更新、插入、选择和删除查询并触发。

    在使用多个 quesris 或单个查询之前有一些提示。

    1) 如果数据库配置为杀死所有花费超过指定时间的查询,那么如果单个查询太大,则使用单个查询可能会导致查询被杀死。 2)另外,如果用户正在等待响应,那么可以使用分页来完成,即现在获取少量记录......稍后获取但不是一条一条。

    【讨论】:

    • 还有max_allowed_packet 需要担心。对于大型插入,LOAD DATA INFILE 通常是最快的方法,如Drew mentioned
    • 但是确实,100 或 1000 的块是无论如何都要走的路(缺少加载数据文件)。插入 tableA (colA,colB) 值 (1,1), (7,4), (8,-19), .... 得到我的肯定
    【解决方案3】:

    对数据库的 5000 次查询不应成为性能瓶颈。你没事。您始终可以对只读运行进行基准测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-18
      • 2014-03-06
      • 1970-01-01
      • 2011-05-06
      • 2011-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多