繁体   English   中英

C# MySQL 超时问题

[英]C# MySQL timeout issues

我正在运行查询时遇到 MySQL 超时问题。 这是一个简单的查询,但即使在 MySQL 编辑器中也需要 5 分钟左右才能完成。 我希望你们可能知道解决此超时问题的更好方法。

            string processedCONString = "SERVER=localhost;" +
                                   "DATABASE=discovery;" +
                                   "UID=;" +
                                   "PASSWORD=;"+
                                   "connection timeout=500000";
        MySqlConnection processCON = new MySqlConnection(processedCONString);
        string mySQLCOMMAND = "update "+ siteString+"_discovery "+
            "set processed = b'0' "
            +"WHERE URL not in (select URL from live)";
        MySqlCommand mysqlprocessCmdInsertItem = new MySqlCommand(mySQLCOMMAND, processCON);
        processCON.Open();
        mysqlprocessCmdInsertItem.ExecuteNonQuery();
        processCON.Close();

是的,UID 和密码在这里留空,但不在代码中。

此外,随着该数据库的增长,查询将花费越来越长的时间。

尝试在 siteString + "_discovery " 返回的表中索引 URL 列。

更新:

另请注意,您在 where 子句和 INNER JOIN 中指定语句的顺序非常重要。 您想知道您的语句何时会导致对每一行执行操作,或者是否会提前完成然后将其应用于行。 有几条规则已经在网上有很好的记录。 其他答案在这里提供了一些很好的建议。 此外,当我在一家大型机构工作时,我总是通过我们的 dba 运行我的 SQL 脚本,然后他们会强烈批评我并抱怨软件开发人员如何总是破坏他的 m* ** f***数据库。 如果你有这样的人,他们通常会很有帮助,因为他们记住了所有这些规则,而我们没有。

谷歌:“sql 查询最佳实践”,你会发现大量的信息。 这是一个链接,

http://blog.sqlauthority.com/2009/01/20/sql-server-rules-for-optimizining-any-query-best-practices-for-query-optimization/

乔纳森汉森的回答是一个不错的选择+1。

如果这还不够,您可以尝试分部分处理。 假设您有一个 ID,您可以将您的代码放在一个 cicle 中,并在每次迭代中处理 1000 个(或您认为合适的数量)项目。

我知道这个线程很古老,Mohgeroth 走在正确的轨道上,但是对于 mysql,查询看起来像这样......

update siteX_discovery
left join live on live.URL = siteX_discovery.URL
set processed = b'0'
where live.URL is null

当然,正如乔纳森指出的那样,您需要索引,否则无论您做什么都会很慢。

就其本身而言,索引在相当长的一段时间内就足够了,但如果您的表变大,消除该子查询将产生明显的差异。

也许我到达了,但试试这个 sql ......

"UPDATE " + siteString + "_discovery as d                 " +
"   SET d.processed = b'0'                                " +
" WHERE d.URL IN (SELECT URL from live where URL = d.URL) ";

与其在子查询中评估整个 select ,不如对其进行过滤,以便在尝试评估父语句中的 where 条件时不会返回每一行。

虽然,子查询将为返回的每一行运行,所以我们可能应该完全删除子查询并让连接来处理这个问题。 由于我们只想对我们可以在 LIVE 表中找到的 URL 执行此操作,因此加入它们应该是平展子查询的小菜一碟……

"UPDATE d                                  " +
"   SET d.processed = b'0'                 " +
"  FROM " + siteString + "_discovery as d  " +
"  JOIN live as l                          " +
"    ON d.URL = l.URL";

此特定更新是在 SQL 服务器上测试的,而不是 MySql 但您可能需要调整事件的顺序才能转换它,我不是 100% 确定,有人可以确认吗?

如果您对异常感到恼火,那么

    mysqlprocessCmdInsertItem.CommandTimeout=1000;

可能会有所帮助(或超时的另一个大数字)。 命令超时默认为 30 秒(仅花费在网络读取计数上的时间)。

暂无
暂无

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

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